Frage von blablubb999, 8

SQL - Einträge finden, die NUR genau diese 2 Werte enthalten?

Hallo Freunde des SQL's. Ich habe mal wieder eine Frage und komme nicht ganz weiter und würde mich freuen, wenn wer eine Idee hat. Ich habe 2 Tabellen. In der ersten Tabelle sind die Bestellungen und in der zweiten ein spezielles Attribut:

Bestellung-Tabelle: ID | Besteller | Produkt | Attribut-ID

Attribut-Tabelle: Attribut-ID | Attribut-Name

Nun steht in der Bestellungstabelle sowas drin:

ID | Besteller | Produkt | Attribut-ID
44 | Mickey Mouse | Waschlappen | 2
44 | Mickey Mouse | Handtuch | 1
13 | Goofy | Waschlappen | 2
88 | Mini Mouse | Zahnbürste | 2
35 | Donald Duck | Waschlappen | 2
35 | Donald Duck | Duschbad | 1
02| Dagobert Duck | Wasserhahn | 5
79 | Trick Duck | Rasierwasser | 4

So ich möchte jetzt per SQL irgendwie angeben, dass ich nur die Zeilen bekomme, die sowohl das Attribut 1 als auch das Attribut 2 haben. Aber es will mir einfach nicht gelingen.

Als Ausgabe erwarte ich also folgende Zeilen:

ID | Besteller | Produkt | Attribut-ID
44 | Mickey Mouse | Waschlappen | 2
44 | Mickey Mouse | Handtuch | 1
35 | Donald Duck | Waschlappen | 2
35 | Donald Duck | Duschbad | 1

Mein erster Versuch war:

select * from Bestellung
WHERE
Attribut-ID = '1' and Attribut-ID = '2'

Mein zweiter Versuch war:

select * from Bestellung b
left join Bestellung b1 on b1.ID = b.ID
left join Bestellung b2 on b2.ID = b.ID
WHERE 
b1.Attribut-ID = '1' and
b2.Attribut-ID = '2'

Aber irgendwie klappt das alles nicht so Recht und langsam bin ich ratlos. Ich würde mich über ein paar Vorschläge sehr freuen.

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von Fregrin, 5

Versuch zum Beispiel mal Folgendes:

SELECT id, besteller, ...
FROM bestellung
WHERE id IN (
SELECT id, count(*) AS anzahl
FROM bestellung
WHERE attributID IN (1,2)
GROUP BY id
HAVING anzahl = 2
)

In dem inneren Select wählst du alle IDs die genau diese 2 Attribute besitzen. 
Der Trick dabei ist die Gruppierung nach ID und das anschließende HAVING, das dann nur noch die IDs leifert, die genau 2 Zeilen liefern. In dem äußeren  Select holst du dir dann alle Informationen die du eigentlich brauchst zu genau diesen IDs.

Natürlich könntest du statt einem SubSelect auch einen Join verwenden, das überlasse ich dir zur Übung ;-)

Antwort
von wotan38, 3

Das passiert Anfängern öfter, dass sie den Unterschied zwischen and und or durcheinanderbringen.

Du suchst Sätze, deren Attribut sowohl 1 als auch 2 ist. Diese Sätze gibt es aber nicht, denn ein Satz kann nur ein Attribut  entweder mit 1 oder mit 2 haben, niemals aber gleichzeitig eine 1 und eine 2. Ein Feld kann immer nur einen Wert annehmen.

Das and und or in der Informatik unterscheidet sich im Gegensatz zum gewöhnlichen Sprachgebrauch streng geregelt nach der Boolschen Algebra. Beim Korrespondieren mit der Datenbank kannst Du nicht und sagen, wenn Du or meinst. Die Datenbank macht das, was Du ihr sagst.

Denke auch daran, dass Du die or-Bedingung ggf. in Klammern setzen musst, wenn sie zusammen mit and-Bedingungen verwendet wird. Auch bei der Abfrage nach ungleich gibt es einiges zu beachten.

Tausche in Deiner Abfrage das and gegen or und dann wird es funktionieren.

Kommentar von blablubb999 ,

Hallo Wotan,

danke erstmal für deine Antwort.

Das mit dem "and" und "or" habe ich eigentlich schon verstanden. Genau deswegen klappt auch das "or" hier auf keinenfall. Denn dann sucht er 'nur' nach einem von beiden und gibt trotzdem wieder die aus, die ich nicht haben will.

Habe aber bereits aus einem Kommentar weiter unten die Lösung bekommen.

Trotzdem hast du das gut erklärt nochmal mit dem "and" und "or" - Danke dafür.

Antwort
von Suboptimierer, 4

Probier mal sowas:

select b.* from bestellung b where 
      exists(select x.* from bestellung x where x.ID = b.ID and x.attribut-id = 1)
  and exists(select y.* from bestellung y where y.ID = b.ID and y.attribut-id = 2)

Sollte jedes Attribut jedem Artikel nur einmal zugeordnet werden können, könntest du das mit COUNT und Abfrage auf =2 abkürzen.

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten