Abfrage mit Left Join und Self Join

MajorHOB

Neuer Benutzer
Beiträge
3
Hallo ich versuche mich gerade an einer Abfrage mit mehreren Tabellen und einem Self Join.
Ich möchte gerne das jede Spalte aus der Tabelle product genau einmal vorkommt.
aidfeat soll entweder 1 oder NULL sein.
bidfeat soll entweder 2 oder NULL sein.

Folgenden SQL Code hab ich verwendet:
Code:
SELECT product.id_product, reference, status, a.id_feature aidfeat, a.id_feature_value aval,  b.id_feature bidfeat, b.id_feature_value bval
FROM product
LEFT JOIN pcupdate ON product.reference = pcupdate.artikelnummer
LEFT JOIN feature_product a ON product.id_product = a.id_product
LEFT JOIN feature_product b ON product.id_product = b.id_product
WHERE (a.id_feature=1 OR a.id_feature IS NULL)

und das ist das Ergebniss:

Code:
 id_product | reference  | status | aidfeat | aval | bidfeat | bval
------------+------------+--------+---------+------+---------+-----
 100        | 19100      | 1      | 1       | 1    | 1       | 1 
 100        | 19100      | 1      | 1       | 1    | 2       | 2
 101        | 1103       | 2      | 1       | 2    | 1       | 2
 102        | 19050      | 2      | NULL    | NULL | NULL    | NULL
 103        | 19100      | 1      | NULL    | NULL | NULL    | NULL
 104        | sdfds      | NULL   | NULL    | NULL | NULL    | NULL

schon nicht schlecht wie ich finde jetzt nur noch die Bedingung für bidfeat eingeben um die erste Zeile auszublenden und in der 3.Zeile bei ID 101 aus bidfeat und bval ein NULL zu zaubern.
Dafür verwede ich folgenden Code:
Code:
SELECT product.id_product, reference, status, a.id_feature aidfeat, a.id_feature_value aval,  b.id_feature bidfeat, b.id_feature_value bval
FROM product
LEFT JOIN pcupdate ON product.reference = pcupdate.artikelnummer
LEFT JOIN feature_product a ON product.id_product = a.id_product
LEFT JOIN feature_product b ON product.id_product = b.id_product
WHERE (a.id_feature=1 OR a.id_feature IS NULL)
AND
(b.id_feature=2 OR b.id_feature IS NULL)

und das ist das Ergebnis:

Code:
 id_product | reference  | status | aidfeat | aval | bidfeat | bval
------------+------------+--------+---------+------+---------+-----
 100        | 19100      | 1      | 1       | 1    | 2       | 2
 102        | 19050      | 2      | NULL    | NULL | NULL    | NULL
 103        | 19100      | 1      | NULL    | NULL | NULL    | NULL
 104        | sdfds      | NULL   | NULL    | NULL | NULL    | NULL

leider schmeißt mir die Abfrage jetzt die ID 101 komplett raus. Welche WHERE Bedingung kann ich verwenden.
Vielen Dank und schönen Abend.
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.173
Hallo ich versuche mich gerade an einer Abfrage mit mehreren Tabellen und einem Self Join.
Ich möchte gerne das jede Spalte aus der Tabelle product genau einmal vorkommt.
aidfeat soll entweder 1 oder NULL sein.
bidfeat soll entweder 2 oder NULL sein.

leider schmeißt mir die Abfrage jetzt die ID 101 komplett raus. Welche WHERE Bedingung kann ich verwenden.
Vielen Dank und schönen Abend.


Zeig bitte, was in den Tabellen steht (mach ne kurze Demo) und was rauskommen soll. Und formatiere es so, daß man es ordentlich sieht.
 

MajorHOB

Neuer Benutzer
Beiträge
3
Ok ich hab es im ersten Beitrag mal etwas leserlicher gemacht
Hier folgen meine Tabellen. Ich habe sie nochmal um einen Fall (id 999) erweitert, der auch noch Auftreten kann.

Code:
 Tabelle "product"
 
 id_product | reference  
------------+------------
 100        | 19100      
 101        | 1103       
 102        | 19050      
 103        | 19100      
 104        | sdfds      
 999        | 99999

Code:
Tabelle "pcupdate"
 
 artikelnummer | Status 
---------------+------------
 1103          | 2      
 19050         | 2       
 19100         | 1      
 19500         | 2      
 18888         | 1

Code:
 Tabelle "feature_product"
 
 id_feature | id_product | id_feature_value 
------------+------------+-----------------
 1          | 100        | 1     
 1          | 101        | 2      
 2          | 100        | 2     
 2          | 999        | 1

und das sollte bei der Abfrage rauskommen

Code:
 id_product | reference  | status | aidfeat | aval | bidfeat | bval
------------+------------+--------+---------+------+---------+-----
 100        | 19100      | 1      | 1       | 1    | 2       | 2
 101        | 1103       | 2      | 1       | 2    | NULL    | NULL
 102        | 19050      | 2      | NULL    | NULL | NULL    | NULL
 103        | 19100      | 1      | NULL    | NULL | NULL    | NULL
 104        | sdfds      | NULL   | NULL    | NULL | NULL    | NULL
 999        | 18888      | 1      | NULL    | NULL | 2       | 1
 

akretschmer

Datenbank-Guru
Beiträge
9.173
Ok ich hab es im ersten Beitrag mal etwas leserlicher gemacht
Hier folgen meine Tabellen. Ich habe sie nochmal um einen Fall (id 999) erweitert, der auch noch Auftreten kann.


Aufgrund massiver Knotenbildung in /dev/brain geb ich auf. Dein doppelter JOIN auf feature_product führt zu einem versteckten cross join. Ich raff Deine Logig nicht und nicht, was das Ziel sein soll. Sorry.
 

ukulele

Datenbank-Guru
Beiträge
4.416
Also dieser Code tut was er soll:
Code:
SELECT product.id_product, reference, status, a.id_feature aidfeat, a.id_feature_value aval,  b.id_feature bidfeat, b.id_feature_value bval
FROM product
LEFT JOIN pcupdate ON product.reference = pcupdate.artikelnummer
LEFT JOIN feature_product a ON product.id_product = a.id_product
LEFT JOIN feature_product b ON product.id_product = b.id_product
WHERE (a.id_feature=1 OR a.id_feature IS NULL)
AND
(b.id_feature=2 OR b.id_feature IS NULL)
...er schmeist alle Werte raus bei denen deine Bedingungen zutreffen:
aidfeat soll entweder 1 oder NULL sein.
bidfeat soll entweder 2 oder NULL sein.

Dir fehlt diese Zeile:
Code:
  id_product | reference  | status | aidfeat | aval | bidfeat | bval
------------+------------+--------+---------+------+---------+-----
101        | 1103      | 2      | 1      | 2    | NULL    | NULL
...die aber so gar nicht existiert nur:
Code:
 id_product | reference  | status | aidfeat | aval | bidfeat | bval
------------+------------+--------+---------+------+---------+-----
 101        | 1103       | 2      | 1       | 2    | 1       | 2
... existiert wenn man sich deinen ersten Select anschaut. Du möchtest also nicht das die Ergebnisse ausgeschlossen werden wie es in der WHERE Bedingung gemacht wird sondern das sie abgeändert werden!

So müsstest du zum Ziel kommen. Ich mach das jetzt mal beispielhaft für den einen Datensatz und nur bidfeat, ich kenne ja nicht alle möglichen Kombinationen und Werte die auftreten können und weiss nicht, wie sie abgeändert werden sollen. Ich Gucke ob der Wert 2 oder NULL ist andernfalls ändere ich den Wert auf NULL ab.:
Code:
SELECT    product.id_product,
        reference,
        status,
        a.id_feature AS aidfeat,
        a.id_feature_value AS aval,
        (    CASE
            WHEN    b.id_feature = 2
            OR        b.id_feature IS NULL
            THEN    b.id_feature
            ELSE    NULL
            END ) AS bidfeat,
        b.id_feature_value AS bval
FROM    product
LEFT JOIN pcupdate ON product.reference = pcupdate.artikelnummer
LEFT JOIN feature_product a ON product.id_product = a.id_product
LEFT JOIN feature_product b ON product.id_product = b.id_product
WHERE (    a.id_feature = 1
OR        a.id_feature IS NULL )
 
Werbung:

MajorHOB

Neuer Benutzer
Beiträge
3
Super ukulele :)

Ich habs zwar noch nicht ausprobiert, aber das sieht richtig gut aus.

Mir ist ein richtiges Licht aufgegangen. Klar wenn ich keine Zeile habe, die meiner gesuchten entspricht, wie soll ich sie dann mit where rausfiltern.
 
Oben