2009-01-26 16 views
8

Załóżmy, że mam dwie tabele, "Rodzic" i "Dziecko". Parent-to-Child to wiele: wiele relacji realizowanych za pośrednictwem standardowej tabeli porównawczej.Wybierz rekord dla rodziców ze wszystkimi dziećmi w SQL

Chcę znaleźć wszystkie rekordy nadrzędnego, do których odwołują się WSZYSTKIE elementy danego zbioru elementów podrzędnych za pomocą języka SQL (w szczególności T-SQL dla MS SQL Server, dopuszczalne są składnie 2005).

Na przykład załóżmy, że mam:

  • przedmiot
  • nadrzędna Alice
  • nadrzędna Bob
  • Child Charlie odwołuje Alice, Bob
  • Dziecko David odwołuje Alicja
  • Child Ewę referencje Bob

Moje cele to:

  • Jeśli mam dzieci Charlie, chcę zestaw wyników obejmuje Alicja i Bob
  • Jeśli mam dzieci Charlie i David, chcę zestaw wyników obejmuje Alice i NIE Bob.
  • Jeśli mam dzieci, Charliego, Davida i Ewę, chcę, żeby w zestawie wyników nikogo nie było.
+0

Jak to jest standardowe FK, jeśli dziecko Charlie może odwołać się zarówno do Alice i Bob? –

+0

W porządku Mark, ludzie, którzy potrzebują pomocy w pisaniu zapytań rzadko mogą zapytać poprawnie. –

+0

Niestety, nie było jasne: Rodzic: Dziecko jest wiele: wiele. –

Odpowiedz

6

Powołując się na trick numerycznej (gdzie liczba linków rodzic-dziecko = liczba dzieci, że rodzic jest powiązany wszystkich dzieci):

SELECT Parent.ParentID, COUNT(*) 
FROM Parent 
INNER JOIN ChildParent 
    ON ChildParent.ParentID = Parent.ParentID 
INNER JOIN Child 
    ON ChildParent.ChildID = Child.ChildID 
WHERE <ChildFilterCriteria> 
GROUP BY Parent.ParentID 
HAVING COUNT(*) = (
    SELECT COUNT(Child.ChildID) 
    FROM Child WHERE <ChildFilterCriteria> 
) 
+0

To podejście, o którym wiedziałem; Miałem nadzieję uniknąć numerycznej sztuczki. Ale twoja odpowiedź i tak jest warta przegranej. :-) –

2

(Chyba, gdzie powiedział: "Dziecko Eve odwołuje Ewę" masz na myśli "Dziecko Eve odwołuje Bob", prawda?)

Chyba mam to ... wygląda brzydko ... sekret jest podwójną negacją ... to znaczy, każdy, dla którego to prawda, jest taki sam jak nie ktokolwiek, dla którego jest fałszywy ... (ok, mam kłopoty z moim angielskim, ale myślę, że rozumiesz co mam na myśli)

 
select * from parent 

parent_id        name 
--------------------------------------- -------------------------------------------------- 
1          alice 
2          bob 

select * from child 

child_id        name 
--------------------------------------- -------------------------------------------------- 
1          charlie 
2          david 
3          eve 

select * from parent_child 

parent_id        child_id 
--------------------------------------- --------------------------------------- 
1          1 
2          1 
1          2 
2          3 

select * from parent p 
where not exists(
    select * from child c 
    where 
     c.child_id in (1, 2, 3) and 
     not exists(
      select * from parent_child pc where 
       pc.child_id = c.child_id and 
       pc.parent_id = p.parent_id 
     ) 
) 

--when child list = (1) 
parent_id        name 
--------------------------------------- -------------------------------------------------- 
1          alice 
2          bob 

--when child list = (1, 2) 
parent_id        name 
--------------------------------------- -------------------------------------------------- 
1          alice 

--when child list = (1, 2, 3) 
parent_id        name 
--------------------------------------- -------------------------------------------------- 

dobrze, mam nadzieję, że to pomaga ...

+0

Tak, zmieszałem referencję Eve-> Bob. Dziękuję za wskazanie tego. –

Powiązane problemy