Union MYSQL中的GROUP BY

时间:2016-11-11 13:58:57

标签: mysql union

我想让每个上课的学生都在场。

条件是:

  1. 所有来自Classroom ID的教室的学生都是< 99和(DropTime<>' 00'和PickupTime =' 00:00')和日期是20161111

  2. 所有来自ClassroomId的教室的学生都是> 99和(DropTime =' 00:00')和日期是20161111

  3. 我在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 个答案:

答案 0 :(得分:1)

必须为每个聚合设置分组。因此,你需要三个小组;每个联合语句都有1个,因为它们都是聚合的,也是外部选择的一个......因为你也在那里聚合。

换句话说,每个查询必须能够在其可以在另一个查询中运行之前对其进行操作。由于缺少组,大多数RDBMS系统中的两个内联查询都会失败,但是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个不同的集合然后将它们组合起来。 / p>

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