2009-04-28 10 views
1

Ich denke, dass ich mit dieser besonderen Situation stecken bin:
wählen Zeilen in einer Eins-zu vielen Situation

Hier sind meine Tabellen:

item_table:
id | Artikel
1: A
2: B
3: C

attr_table:
attr | item_id
1: 1
1: 2
2: 1
2: 3
3: 2
3: 3
Ich würde gerne wissen, ob es technisch möglich ist, ein beliebiges Element abzurufen, die verbunden ist mit attr = 1 und 3. Die Antwort sollte nur "B" sein. Ebenso, wenn ich ein Element anfrage, das mit attr = 1 und 2 verknüpft ist, sollte ich nur 'A' bekommen.

Die Sache ist, dass attr_table potenziell viele Zeilen haben kann und ich möchte nur eine Abfrage machen.

Diese Frage klingt einfach und ich bin ziemlich verärgert darüber, dass ich sie nicht beantworten kann.

Ich hatte gehofft, dass jemand klüger könnte mir eine Hand ...

Antwort

2

Das Beispiel für SQLServer geschrieben wird, aber die Abfrage sollte in mysql als wel arbeiten.

Schlüssel ist die HAVING COUNT-Anweisung, die der Menge der Attribute entspricht, die übereinstimmen müssen. Wenn die Attribute sein sollte (1, 2, 5), werden Sie die Zählung 3.

DECLARE @item_table TABLE (ID INTEGER PRIMARY KEY, Item CHAR(1)) 
DECLARE @attr_table TABLE (Attr INTEGER, Item_ID INTEGER) 

INSERT INTO @item_table VALUES (1, 'A') 
INSERT INTO @item_table VALUES (2, 'B') 
INSERT INTO @item_table VALUES (3, 'C') 

INSERT INTO @attr_table VALUES (1, 1) 
INSERT INTO @attr_table VALUES (1, 2) 
INSERT INTO @attr_table VALUES (2, 1) 
INSERT INTO @attr_table VALUES (2, 3) 
INSERT INTO @attr_table VALUES (3, 2) 
INSERT INTO @attr_table VALUES (3, 3) 


SELECT Item 
FROM @item_table i 
    INNER JOIN @attr_table a ON a.Item_ID = i.ID 
WHERE a.Attr IN (1, 3) 
GROUP BY Item 
HAVING COUNT(a.Attr) = 2 
+0

Ist eine innere Verbindung nicht gleichbedeutend mit einer zweiten Auswahl? –

+0

Dies ist zerbrechlich, mit dem 'count =', da es nicht funktionieren wird, wenn es genau zwei attr-Zeilen gibt, die dem Element mit den angegebenen attrs entsprechen. Aber schlimmer, es scheitert, wenn es zwei attr-Zeilen mit item_id = 1 und attr = 1 gibt - also bringt es ein falsches positives zurück, ein Element ohne attr = 3. Und es addiert die Kosten einer Gruppe um. – tpdi

+0

@Blank Xavier, es tut mir leid, aber ich verstehe nicht, was Sie versuchen zu bekommen. –

0
select distinct item_table.item from item_table, attr_table 
where item_table.id = attr_table.item_id 
and attr_table.attr = 1 and attr_table.attr = 3; 

Grundsätzlich ändern müssen sie tut das passende man erwarten würde und endet mit einer Tonne rows - aber dann funktioniert das distinct-Schlüsselwort, so dass Sie den minimalen eindeutigen Satz von Zeilen als Endergebnis erhalten.

(Interally, ich hoffe, es ist effizienter, aber nicht die vollständige Liste der übereinstimmenden Zeilen zu machen).

+1

Funktioniert nicht wirklich, da es keine einzelne Zeile gibt, in der "attr = 1 und attr = 2" wahr ist. –

+0

Ich verstehe es nicht. Ist die '2' ein Tippfehler? sollte es "3" sein? –

1
SELECT * From attr_table a, item_table i 
    where a.item_id = i.id 
    and a.attr = 1 
    and a.item_id in (select item_id from attr_table where attr = 3); 

Wird der Job

1
select * from item_table a 
where exists (select * from attr_table b 
       where b.item_id = a.id and b.attr = 1) 
and exists (select * from attr_table c 
      where c.item_id = a.id and c.attr = 3); 

Beachten Sie, dass diese Abfrage sagt genau das, was Ihre Spezifikation sagt eine Zeile für Punkt B. Rückkehr: Holen Sie mir alle Zeilen aus item_table, wo es existiert zumindest eine Reihe von attr_table mit der ID dieser Zeile und dem ersten attr, das und angegeben wird, wenn mindestens eine Zeile aus attr_table vorhanden ist, für die die ID dieser Zeile und das zweite attr angegeben wurde.

0

Dies ist wahrscheinlich viel zu spät, aber ich würde vorschlagen, ein paar schließt sich wie so mit:

select i.item, b.item_id, c.item_id 
from item_table i 
join attr_table b on i.id=b.item_id and b.item_id=1 
join attr_table c on i.id=c.item_id and c.item_id=2 

Das ist, wie ich es tun.

Verwandte Themen