Gleiche Datensätze aus 2 Tabellen ziehen

timestamp

Mitglied Käsekuchen
Hallo Forum,

Ich kopiere zur Zeit eine alte Datenbank in eine neue (die neue Datenbank hat eine andere Struktur).

Ich habe nun zwei Tabellen A und B:
Code:
--A
id, a1, a2, a3

--B
id, b1, b2, b3, ... b15
Jeweils 3 Felder aus b wurden in die Felder a1-3 kopiert.
Also b1,b2,b3 in a1,a2,a3, b4,b5,b6 in a1,a2,a3 usw.
Hierbei: Bei b1-b3 ist immer mindestens b1 nicht NULL, b4-b15 kann komplett NULL sein (die wurden auch nicht kopiert).

Um jetzt die alte Beziehung herstellen zu können, brauche ich die zugehörige ID aus B.

Ich suche also (zunächst) alle b1, b2, b3 die mit a1, a2, a3 übereinstimmen. (später dann entsprechend b4-b6, b7-b9...)
Mir werden aber viel zu wenig Datensätze angezeigt und ich weiß nicht warum.
Ich erhalte nur knapp 150, statt der über 800 vorhandenen.

Ich hoffe ich konnte das Problem deutlich genug beschreiben.
Hier mein Query:
SQL:
SELECT * FROM a, b
WHERE(
	(
	a.a1 = b.b1
	AND
	a.a2 = b.b2
	AND
	a.a3 = b.b3
	)
	OR
	(
	a.a1 = b.b1
	AND
	a.a2 IS NULL AND b.b2 IS NULL
	AND
	a.a3 = b.b.3
	)
	OR
	(
	a.a1 = b.b.1
	AND
	a.a2 = b.b2
	AND
	a.a3 IS NULL AND b.b3 IS NULL
	)
	OR
	(
	a.a1 = b.b1
	AND
	a.a2 IS NULL AND b.b2 IS NULL
	AND
	a.a3 IS NULL AND b.b.3 IS NULL
	)
)

Die Felder sind übrigens alle vom Typ VarChar

edit:
Um es vielleicht noch ein wenig zu verdeutlichen:
Tabelle b hat 15 Felder, die aus 5 Dreiergruppen bestehen.
Diese habe ich in Tabelle a aufgelöst, so dass ein Datensatz in a eine 3er Gruppe in b repräsentiert.
Eine Dreiergruppe ist nicht leer, wenn das jeweils 1. Element nicht NULL ist.
Ein kompletter Datensatz in B kann z.b. so aussehen (3er Gruppen sind kenntlich gemacht):
Code:
aaa,bbb,ccc|ddd, NULL, fff|ggg, NULL, NULL|jjj, kkk, lll| NULL, NULL, NULL
In a steht dann:
Code:
aaa,bbb,ccc
ddd,NULL,fff
ggg, NULL, NULL
jjj, kkk, lll
 
Zuletzt bearbeitet:
Bring doch einfach mal mit einem UNION die Tabelle B in die Form von A. DIe NULL in der ersten Spalte ist eigentlich egal

SQL:
SELECT id, b1, b2, b3 FROM tableB
UNION ALL SELECT id, b4, b5, b6 FROM tableB	
UNION ALL SELECT id, b7, b8, b9 FROM tableB	
UNION ALL SELECT id, b10, b11, b12 FROM tableB	
UNION ALL SELECT id, b13, b14, b15 FROM tableB

Dann noch die Tabelle A anhängen und fertig
SQL:
SELECT
	a.id,
	b.id AS b_id
FROM
	tableA AS a
	LEFT JOIN (
		SELECT id, b1, b2, b3 FROM tableB
		UNION ALL SELECT id, b4, b5, b6 FROM tableB	
		UNION ALL SELECT id, b7, b8, b9 FROM tableB	
		UNION ALL SELECT id, b10, b11, b12 FROM tableB	
		UNION ALL SELECT id, b13, b14, b15 FROM tableB	
	) AS b
		ON a.a1 = b.b1
		AND IFNULL(a.a2, 'NULL') = IFNULL(b.b2, 'NULL')
		AND IFNULL(a.a3, 'NULL') = IFNULL(b.b3, 'NULL')

Nachtrag: Hab noch das IFNULL() in die ON-Sektion gepastet um die NULL-Werte zu vergleichen.
 
Zuletzt bearbeitet von einem Moderator:
Hallo yaslaw,

vielen Dank für deine Mühen.
Die Schreibweise mit IFNULL ist sehr interessant. Ich habe es auch schon bei google gefunden, allerdings ohne ein sinnvolles Anwendungsbeispiel, das wird mir hier jetzt eindeutig klarer. Das macht den Query ja um einiges eleganter (ich vermute ebenfalls perfomanter).
Das Problem war tatsächlich ganz trivial, der import in Tabelle A war fehlerhaft, was mir blöderweise erst nach Stundenlanger Arbeit aufgefallen ist.
Eine Frage hat sich allerdings neu ergeben:
Wenn ich eine UNIQUE index über a1, a2 und a3 gleichzeitig setzen möchte, wie geht das?
Scheinbar hat das den Fehler beim import ausgelöst, da einige Datensätze nicht übernommen wurden.
 
SQL:
create unique index <index name> on <table name>
(
a1,
a2,
a3
);

Aber Achtung bei Nullabe! Bei InnoDB und MyISAM kann es Duplikate mit NULL geben. Bei BDB nicht.
 
Zuletzt bearbeitet von einem Moderator:
Die Schreibweise mit IFNULL ist sehr interessant. Ich habe es auch schon bei google gefunden, allerdings ohne ein sinnvolles Anwendungsbeispiel, das wird mir hier jetzt eindeutig klarer. Das macht den Query ja um einiges eleganter (ich vermute ebenfalls perfomanter).
IFNULL() ist einer der besten BEfehle. Gäbe es ihn nicht, müsste man ihn erfinden.

Ich verwende ihn immer bei der Summenbildung, wenn die technische Möglichkeit besteht (Das Feld ist nullable) dass ein Wert NULL ist. Weil mit NULL lässt sich nicht rechnen

SQL:
-- Summenbildug
SUM(IFNULL(field1, 0)) AS sum_a

-- sonstige Formeln
-- (a+b)/c
(IFNULL(field1, 0) + IFNULL(field2, 0))/IFNULL(field3, 0) AS calc
 
Zuletzt bearbeitet von einem Moderator:
Klugscheisser :)
Hast natürlich Recht.
SQL:
(IFNULL(field1, 0) + IFNULL(field2, 0))/field3 AS calc
 
Zuletzt bearbeitet von einem Moderator:

Neue Beiträge

Zurück