2015-05-28 9 views
8

Ich habe eine Tabelle von Menschen, die einen Namen, Standort (wo sie leben) und eine Parent-ID (Eltern sind in einer anderen Tabelle gespeichert). So zum Beispiel:Zähle SQL-Datensätze basierend auf Geschwister-Eigenschaft

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 

Ich brauche von zu zählen, wie viele Menschen in Chicago leben und Geschwister (teilen sich ein parent_id), die in New York leben. So zum Beispiel oben würde die Zählung 3. sein

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 

Kann mir jemand helfen, die SQL schreiben diese Zählung abfragen?

Antwort

1

Die korrelierte Abfrage ist ein sehr schöner Weg und ist sehr effizient. Vermeiden Sie die Verwendung von distinct, da es eine teure Operation ist. Group by ist eine nette Alternative gegenüber der Verwendung von distinct. Verstehen Sie die Daten und strukturieren Sie die Abfrage entsprechend. Hier ist eine andere Option, die Engine-optimierte ...

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

Dies sind keine korrelierten Unterabfragen, sie sind nur Unterabfragen, und Ihre Antwort leidet unter dem gleichen Problem, das PD1ce anfangs hatte; es wird Leute in Chicago mit N Geschwistern in New York N mal zählen. – Uueerdo

1

Vielleicht versuchen Sie das?

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

Sieht aus wie Minhs Antwort funktioniert gut, aber hier ist ein weiteres Beispiel mit einem 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' 

Sollte "3" für nur die obige Tabelle aufgeführt werden.

EDIT: Eine DISTINCT a.parent_id basierend auf Lithis 'Vorschlag hinzugefügt.

EDIT2: Wie von Uueerdo erwähnt, würde eine child_id oder eine Art eindeutige ID im Fall von 2 Geschwistern, die in Chicago leben, und 1 Geschwister, die in New York leben, wirklich helfen. Ich habe die ursprüngliche Abfrage bearbeitet, um dies zu berücksichtigen.

Da dies nicht wirklich eine "Antwort" auf Ihre Frage ist, weil es keine solche child_id gibt, würde ich auf Uueerdos Antwort verzichten, sorry!

+0

Ich habe nicht die Abfrage ausgeführt, aber es scheint, als würde es eine einzelne Person zweimal zählen, wenn sie zwei verschiedene Geschwister in New York haben. Vielleicht würde dies das Hinzufügen von GROUP BY a.id oder das Verwenden von COUNT (DISTINCT a.id) verhindern. – Lithis

+0

Sie sind richtig Lithis, habe das nicht verstanden. Ich werde meinen Beitrag bearbeiten. – PD1ce

+0

Sie brauchen wirklich eine "Kinder ID", wenn zwei Personen in Chicago die gleichen Eltern haben, werden sie nur einmal gezählt. Würde "COUNT (DISTINCT a. *)" Vielleicht funktionieren? – 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' 
     ) 
; 

Mit Minh als Basis sollte dies ziemlich schnell sein; Da die Unterabfrage nicht länger "korreliert" ist, sollte nicht die Möglichkeit bestehen, dass sie wiederholt ausgeführt werden muss, einmal für jede Zeile in people.