
在数据库管理中,我们经常需要对数据进行分组并计算每组的总数。例如,统计每个司机的出勤总次数。以下是一个典型的SQL查询,用于从employees和callouts表中获取每个司机的总出勤次数:
SELECT
    e.driver,
    c.id,
    MAX(c.date) AS latest_callout_date,
    COUNT(*) AS total_callouts
FROM
    employees e,
    callouts c
WHERE
    e.id = c.id AND e.status = 0
GROUP BY
    e.driver
ORDER BY
    e.driver;这个查询会返回类似以下的结果,显示每个司机的总出勤次数:
| DRIVER | ID | LATEST_CALLOUT_DATE | TOTAL_CALLOUTS | 
|---|---|---|---|
| BILL | 2 | 2021-11-09 | 9 | 
| FRED | 8 | 2021-11-01 | 6 | 
| TOM | 4 | 2021-11-03 | 3 | 
然而,实际业务需求往往更复杂。假设callouts表中有一个名为EXCUSED的列,其中0表示已请假(excused),1表示未请假(unexcused)。现在,我们不仅需要知道总的出勤次数,还需要单独统计每个司机的“未请假”次数。
当一个字段的值是布尔型(例如,0代表假,1代表真),或者可以被视为布尔型时,SUM()函数可以非常巧妙地用于条件计数。
在我们的例子中,EXCUSED列的值为0(已请假)或1(未请假)。因此,对EXCUSED列求和,将直接得到未请假(EXCUSED = 1)的总次数。
为了在现有查询中添加未请假次数的统计,我们只需在SELECT子句中加入SUM(c.excused):
SELECT
    e.driver,
    c.id,
    MAX(c.date) AS latest_callout_date,
    COUNT(*) AS total_callouts,
    SUM(c.excused) AS unexcused_absences -- 新增的列
FROM
    employees e,
    callouts c
WHERE
    e.id = c.id AND e.status = 0
GROUP BY
    e.driver
ORDER BY
    e.driver;代码解释:
执行此查询后,您将获得包含未请假次数的新结果列:
| DRIVER | ID | LATEST_CALLOUT_DATE | TOTAL_CALLOUTS | UNEXCUSED_ABSENCES | 
|---|---|---|---|---|
| BILL | 2 | 2021-11-09 | 9 | 2 | 
| FRED | 8 | 2021-11-01 | 6 | 1 | 
| TOM | 4 | 2021-11-03 | 3 | 0 | 
使用明确的JOIN语法: 推荐使用ANSI SQL的INNER JOIN ... ON语法来连接表,而不是在WHERE子句中隐式连接。这提高了查询的可读性和维护性。
SELECT
    e.driver,
    c.id,
    MAX(c.date) AS latest_callout_date,
    COUNT(*) AS total_callouts,
    SUM(c.excused) AS unexcused_absences
FROM
    employees e
INNER JOIN
    callouts c ON e.id = c.id
WHERE
    e.status = 0
GROUP BY
    e.driver
ORDER BY
    e.driver;更复杂的条件计数: 如果您的条件不仅仅是0/1布尔值,或者需要基于更复杂的逻辑进行计数,可以使用CASE表达式结合SUM()。例如,统计某个特定类型的未请假:
SUM(CASE WHEN c.excused = 1 AND c.absence_type = 'Sick' THEN 1 ELSE 0 END) AS unexcused_sick_absences
数据类型: 确保用于SUM()的列的数据类型是数值型(如INT, TINYINT等),以便正确进行求和操作。如果列是布尔型(BOOLEAN),在某些数据库中会自动转换为0或1。
性能优化: 确保WHERE子句中使用的列(如employees.status)和JOIN条件中的列(如employees.id, callouts.id)以及GROUP BY子句中的列(如employees.driver)上都有适当的索引,以提高查询性能。
通过在GROUP BY查询中巧妙地使用SUM()函数对布尔型(0/1)字段进行求和,我们可以非常简洁高效地实现条件计数的需求。这种方法避免了复杂的子查询或多次查询,直接在一次聚合操作中获取所需的所有统计信息,从而提升了查询效率和代码可读性。在处理类似统计特定事件或状态数量的场景时,这种技术是SQL开发者的有力工具。
以上就是SQL教程:在分组查询中高效计算条件总数的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                
                                
                                
                                
                                
                                
                                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号