PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SQL Query formen


Gast
2007-05-14, 23:32:01
Tabelle 'category_values a', über ein WHERE statement gilt cv_cat_id IN(107, 106) und cv_detail_id = 56

cv_id | cv_cat_id | cv_detail_id
---------------------------
1 | 107 | 56
2 | 106 | 56
3 | 1 | 57
4 | 2 | 58


Tabelle 'categories b' wird auf b.c_id = a.cv_cat_id angejoint.

c_id | c_name
-------------
107 | Nok
12 | Sie

Tabelle 'categories c' wird auf c.c_id = 110 angejoint (die Nummer ist bekannt bei Ausführung).

c_id | c_name | c_detail_id
-------------
110 | Her | 12

Tabelle 'category_values d' wird über d.cv_cat_id = c.c_id und d.cv_detail_id = c.c_detail_id angejoint

cv_id | cv_cat_id | cv_detail_id
---------------------------
7 | 110 | 12
8 | 110 | 12
9 | 2 | 57

Tabelle 'language e' soll über e.l_key = CONCAT('vc_',d.cv_id) und e.l_lang = 8 angejoint werden (Nummer ist da bekannt).

l_key | l_string | l_lang
---------------------------
cv_7 | ABC | 8
cv_8 | DEF | 27
cv_9 | G | 8

Ich will als Ergebnis

b.c_id | b.c_name | c.c_id | d.cv_id | e.l_key | e.l_string
-------|----------|--------|--------|--------|----------
107 | Nok | 110 | 7 | cv_7 | ABC

Das Problem ist jetzt, dass in Tabelle d zwei Datensätze mit cv_cat_id = 110 und cv_detail_id = 12 vorkommen, Ergebnis eines LEFT JOIN ist hier dann NULL.

Mein Versuch:
SELECT a. * , b. * , c. * , d. * , e. *
FROM category_values a
LEFT JOIN categories b ON ( b.c_id = a.cv_cat_id)
LEFT JOIN categories c ON ( c.c_id =110 )
LEFT JOIN category_values d ON ( d.cv_cat_id = c.c_id
AND d.cv_detail = c.c_detail_id )
LEFT JOIN language e ON ( e.l_key = CONCAT( 'cv_', d.cv_id AND e.l_lang =8) )
WHERE a.cv_cat_id
IN ( 107, 106 )
AND a.cv_detail_id = 56

gereggter Gast
2007-05-15, 00:24:59
Einfach die weitere where-Bedingung 'isnull(e.l_string) = false' hinzuzufügen, ist wohl zu offensichtlich :|, weshalb ich denke, du suchst nach einem SQL-igen Kniff.

Gast
2007-05-15, 00:47:49
Das geht doch garnicht (ausprobiert natürlich), in der Ergebnismenge ist überall l_string = NULL, mit deiner zusätzliche Bedingung bekomme ich dann natürlich gar keine Datensätze zurück...

Was ich eigentlich brauche, ist ein Statement, das erst einmal eine Ergebnismenge aus dem Join von Tabelle e und d über e.l_key = CONCAT('cv_'.d.cv_id) erstellt, da können nämlich immer nur 2 Datensätze angejoint werden, UND DANN mittels e.l_lang = 8 den einen der beiden Datensätze an die Gesamtergebnissmenge anhängt/joint.

Und da habe ich gerade keine Idee...

gereggter Gast
2007-05-15, 01:36:41
Wenn ich das in Gedanken durchspiele, erhalte ich immer eine Zeile, in der die Spalten von e mit Werten gefüllt sind, sowie eine, in der die Spalten für e nicht gefüllt sind (resultierend aus den zwei Einträgen von d und l_lang für den l_key 'cv_8' eben nicht 8 ist). Weshalb ich auch annahm, dass es mit dem einfachen isnull-Befehl funktionieren müsste.

Diese Zeile:LEFT JOIN language e ON ( e.l_key = CONCAT( 'cv_', d.cv_id AND e.l_lang =8) ) ist aber gewiss nur ein Schreibfehler von dir, oder?

Gast
2007-05-15, 01:41:19
Ja, das ist ein Schreibfehler. Korrekt ist:

LEFT JOIN language e ON ( e.l_key = CONCAT( 'cv_', d.cv_id) AND e.l_lang =8 )

Ich seh schon langes Duschen vor mir...

Marscel
2007-05-15, 13:41:30
Der Threadersteller war ich auf Arbeit.

Mir ist jetzt nur eingefallen, den Query zu splitten, den ersten bis zur Tabelle c joinen, da ist nämlich in jeder Tabelle bei allen Bedingungen nur immer ein Datensatz betroffen, und dann mittels der Ergebnisse aus c über das Programm diese in einen neuen Query einzufügen: (noch nicht ausprobiert)

SELECT * FROM category_values d LEFT JOIN language e ON (e.l_key = CONCAT('cv_',d.cv_id)) WHERE e.l_lang = 8 AND d.cv_cat_id = $cv_cat_id AND d.cv_detail_id = $cv_detail_id

Dann bekomme ich an sich zwei Datensätze geliefert, aber aus der Ergebnismenge nur das, wo entsprechend die Sprache so ist, einen. Aber geht das nicht irgendwie in einen Query gepackt? Ich hasse es, verschachtelt Queries ausführen zu müssen...

gereggter Gast
2007-05-16, 19:48:50
Habe jetzt mal eine Datenbank nach deinen Angaben gebaut und entsprechend mit Daten gefüllt.
Wenn ich dein obiges Query ausführe, erhalte ich vier mögliche Ergebnisse.
Zwei Ergebnisse, wo die Werte für c_id und c_name 'null' sind (durch das linke joinen mit categories b, in der es keine c_id mit dem Wert 106 gibt).
Sowie zwei Ergebnisse, mit den c_id-Wert 107.

Wenn ich jetzt noch isnull(e.l_string)=false zur where-Klausel hinzufüge, fallen zwei Ergebnisse weg. Das von dir genannte Problem - und sei es auch nur schlecht formuliert - tritt nicht auf. Dir bei einem nicht nachvollziehbaren Problem zu helfen (weder theoretisch, noch praktisch), ist also nicht gerade leicht. :eek: