2016-11-11 3 views
0

Я пытаюсь получить количество студентов в классе, которые присутствуют.GROUP BY in Union MYSQL

условия являются:

  1. Все студенты из классов, где ClassroomID является < 99 и есть (DropTime <> '00: 00' и PickUpTime = '00: 00') и дата 20161111

  2. Все студенты из классов, где ClassroomId составляет> 99 и есть (DropTime = '00: 00') и дата 20161111

Я использую ю е следующий запрос в MySQL, и он отлично работает, и я получаю правильный результат:

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 

кроме того, что, когда я пытаюсь сделать профсоюз, чтобы получить результаты для другого класса (т.е. ClassroomID> 99) он не приносит каждый класс и только приносит 1 класс с общим счетом. Это запрос объединения, который я использую;

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 

ответ

1

Группа должна быть на месте для каждой агрегации. Таким образом, вам нужно три группы; 1 для каждого из утверждений объединения как для агрегирования, так и для внешнего выбора ... поскольку вы также агрегируете его.

Другими словами, каждый запрос должен иметь возможность работать самостоятельно, прежде чем он сможет работать в другом. Ваши два встроенных запроса потерпят неудачу в большинстве систем РСУБД из-за отсутствия группы, однако расширенная группа MYSQL усложняет это.

Однако может быть более эффективный способ написания запроса ... Но вот рабочая версия, основанная на вашей внутренней попытке.

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 

Это, кажется, проще и должны достичь тех же результатов (при условии, что я не ввернуть что-то), и это должно быть быстрее, так как он не должен генерировать 3 различных наборов, а затем объединить их.

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

Отличное спасибо! – snowflakes74

 Смежные вопросы

  • Нет связанных вопросов^_^