2015-05-28 24 views
8

Mam tabelę osób, które mają nazwę, lokalizację (gdzie mieszkają) i identyfikator_połączenia (rodzice są przechowywane w innej tabeli). Tak na przykład:Policz rekordy SQL na podstawie właściwości rodzeństwa

name | location | parent_id 
--------+-----------+----------- 
Joe  | Chicago | 12 
Sammy | Chicago | 13 
Bob  | SF  | 13 
Jim  | New York | 13 
Jane | Chicago | 14 
Dave | Portland | 14 
Al  | Chicago | 15 
Monica | Boston | 15 
Debbie | New York | 15 
Bill | Chicago | 16 
Bruce | New York | 16 

muszę policzyć, ilu ludzi mieszka w Chicago i mają rodzeństwa (dzielić parent_id), który mieszka w Nowym Jorku. Tak na powyższym przykładzie, liczba byłaby 3.

name | location | parent_id 
--------+-----------+----------- 
Joe  | Chicago | 12 
Sammy | Chicago | 13 * sibling Jim lives in New York 
Bob  | SF  | 13 
Jim  | New York | 13 
Jane | Chicago | 14 
Dave | Portland | 14 
Al  | Chicago | 15 * sibling Debbie lives in New York 
Monica | Boston | 15 
Debbie | New York | 15 
Bill | Chicago | 16 * sibling Bruce lives in New York 
Bruce | New York | 16 

Może ktoś mi pomóc napisać SQL zapytanie do tej liczby?

Odpowiedz

1

Korelowane zapytanie to bardzo przyjemny sposób na wykonanie i jest bardzo wydajne. Unikaj używania różnych, ponieważ jest to droga operacja. Grupowanie według jest dobrą alternatywą w stosunku do używania różnych. Zapoznaj się z danymi i odpowiednio skonstruuj zapytanie. Oto inna opcja, która jest zoptymalizowana pod kątem silnika ...

select count(*) 
from (select * from #t where Location = 'Chicago') ch 
inner join (select * from #t where Location = 'New York') ny on ch.ParentID = ny.ParentID 
+0

To nie są skorelowane podzapytania, są tylko podkwerendami, a twoja odpowiedź cierpi z powodu tego samego problemu, który początkowo zrobił PD1ce; będzie liczył ludzi w Chicago z N rodzeństwem w Nowym Jorku N razy. – Uueerdo

1

Może spróbuj tego?

SELECT Count(*) 
FROM table table1 
WHERE table1.location= 'Chicago' 
     AND EXISTS (SELECT * FROM table table2 
        WHERE table1.parent_id= table2.parent_id 
          AND table2.location= 'New York') 
3

Wygląda na to, że odpowiedź Minha działa wspaniale, ale tutaj jest inny przykład z użyciem Self Join.

SELECT Count(DISTINCT a.child_id) 
FROM people a 
    JOIN people b ON a.parent_id = b.parent_id 
WHERE a.location = 'Chicago' AND b.location = 'New York' 

Powinny wytwarzać "3" tylko dla powyższej tabeli.

EDYCJA: Dodano DISTINCT a.parent_id na podstawie sugestii Lithisa.

EDIT2: Jak zauważył Uueerdo, identyfikator child_id lub jakiś unikalny identyfikator naprawdę pomogłoby dwóm rodzeństwu mieszkającemu w Chicago i jednemu rodzeństwu mieszkającemu w Nowym Jorku. Zmieniłem oryginalne zapytanie, aby to odzwierciedlić.

Ponieważ nie jest to naprawdę "odpowiedź" na twoje pytanie, ponieważ nie ma takiego child_id, odradzam odpowiedź Uueerdo, przepraszam!

+0

Nie uruchomiłem kwerendy, ale wygląda na to, że policzyłoby się jedną osobę dwukrotnie, jeśli mają dwa różne rodzeństwa w Nowym Jorku. Być może dodanie 'GROUP BY a.id' lub użycie' COUNT (DISTINCT a.id) 'zapobiegnie temu. – Lithis

+0

Masz rację, Lithis, nie złapał tego. Będę edytować mój post. – PD1ce

+0

Naprawdę potrzebujesz "identyfikatora dziecka", jeśli dwie osoby w Chicago mają tego samego rodzica, będą one liczone tylko raz. Właściwie, czy "COUNT (DISTINCT a. *)" Może działać? – Uueerdo

1
SELECT COUNT(*) 
FROM `people` AS p1 
WHERE p1.`location` = 'Chicago' 
     AND p1.parent_id IN (
     SELECT DISTINCT parent_id 
     FROM `people` AS p2 
     WHERE p2.`location` = 'New York' 
     ) 
; 

Używanie Minha jako bazy powinno być dość szybkie; ponieważ podzapytanie nie jest już "skorelowane", nie powinno ryzykować możliwości jego wielokrotnego wykonywania, raz dla każdego wiersza w people.

Powiązane problemy