2016-11-11 9 views
0

Ich versuche, die Anzahl der Schüler pro Klasse, die anwesend sind, zu erhalten.GROUP BY in Union MYSQL

Die Bedingungen sind:

  1. Alle Schüler aus den Klassenzimmern, wo ClassroomID ist < 99 und haben (DropTime <> '00: 00' und PickupTime = '00: 00') und das Datum ist 20161111

  2. Alle Schüler aus den Klassenzimmern, wo ClassroomId> 99 und hat (DropTime = '00: 00') und Datum 20161111

Ith ist mit ist e folgende Abfrage in MySQL und es funktioniert gut und ich bekomme das richtige Ergebnis:

SELECT 
    COUNT(a.Id) AS total, c.Name 
FROM 
    Attendance a 
INNER JOIN 
    Classroom c ON a.classroom = c.Id 
WHERE 
    DropDate = '20161111' 
AND DropTime <> '00:00' 
AND PickupTime = '00:00' 
GROUP BY Name 

der Ausnahme, dass, wenn ich versuche, eine Gewerkschaft zu tun, um die Ergebnisse für eine andere Klasse zu erhalten (dh ClassroomID> 99) es bringt nicht jeder Klassenzimmer und bringt nur 1 Klassenzimmer mit Gesamtanzahl. Dies ist die Union-Abfrage, die ich verwende;

SELECT 
SUM(total), Name 
FROM 
(SELECT 
    COUNT(a.Id) AS total, c.Name 
FROM 
    Attendance a 
INNER JOIN Classroom c ON a.classroom = c.Id 
WHERE 
    DropDate = '20161111' 
     AND DropTime <> '00:00' 
     AND PickupTime = '00:00' 
     AND c.Id < 99 
UNION ALL 
    SELECT 
    COUNT(a.Id) AS total, c.Name 
FROM 
    Attendance a 
INNER JOIN Classroom c ON a.classroom = c.Id 
WHERE 
    DropDate = '20161111' 
     AND PickupTime = '00:00' 
     AND c.Id > 99) t 
GROUP BY Name 

Antwort

1

Gruppen von 's müssen für jede Aggregation vorhanden sein. Also brauchst du drei Gruppen nach denen; 1 für jede der Union-Anweisungen, da beide aggregieren sowie eine für die äußere Auswahl ... da Sie auch aggregieren.

Anders ausgedrückt, jede Abfrage muss in der Lage sein, eigenständig zu arbeiten, bevor sie innerhalb eines anderen operieren kann. Ihre zwei Inline-Abfragen würden in den meisten RDBMS-Systemen aufgrund der fehlenden Gruppierung fehlschlagen, die erweiterte Gruppe von MYSQL macht dies jedoch komplizierter.

Allerdings gibt es möglicherweise eine effizientere Möglichkeit, die Abfrage zu schreiben ... Aber hier ist eine funktionierende Version basierend auf Ihrem ersten Versuch.

SELECT 
SUM(total), Name 
FROM 
(SELECT 
    COUNT(a.Id) AS total, c.Name 
FROM 
    Attendance a 
INNER JOIN Classroom c ON a.classroom = c.Id 
WHERE 
    DropDate = '20161111' 
     AND DropTime <> '00:00' 
     AND PickupTime = '00:00' 
     AND c.Id < 99 
GROUP BY c.name 
UNION ALL 
    SELECT 
    COUNT(a.Id) AS total, c.Name 
FROM 
    Attendance a 
INNER JOIN Classroom c ON a.classroom = c.Id 
WHERE 
    DropDate = '20161111' 
     AND PickupTime = '00:00' 
     AND c.Id > 99 
GROUP BY c.name) t 
GROUP BY t.name 

Dies scheint simplier zu sein und die gleichen Ergebnisse (sofern ich Schraube nicht etwas nach oben) erreichen, und es sollte schneller sein, da es nicht drei verschiedene Sätze zu erzeugen hat und sie dann kombinieren.

SELECT COUNT(a.Id) AS total 
    , c.Name 
FROM Attendance a 
INNER JOIN Classroom c 
    ON a.classroom = c.Id 
WHERE DropDate = '20161111' 
    AND ((DropTime <> '00:00' AND PickupTime = '00:00' AND c.Id < 99) 
    OR (PickupTime = '00:00' AND c.Id > 99)) 
GROUP BY c.name 
+0

Perfekt danke! – snowflakes74