如何在没有&#34的情况下对“SUM”进行“HAVING”;在HAVING子句"中使用非分组字段x

时间:2017-11-17 11:20:43

标签: sql grouping mariadb having

所以,我有这个查询,它在HeidiSQL中运行良好,但由于严格模式而不在Laravel中(更具体地说可能是因为设置了SQL模式ONLY_FULL_GROUP_BY):

SELECT
    project.id
        'Project code',
    SUM(report.hours)
        'Total hours',
    SUM(CASE WHEN report.date BETWEEN :report_start AND :report_end THEN report.hours END)
        'Total report hours'

FROM report
    INNER JOIN project ON project.id = report.id
WHERE report.date <= :report_end

GROUP BY
    project.id

HAVING
    `Total report hours` != 0

它给了我以下错误:

  

语法错误或访问冲突:1463非分组字段&#39;报告总时数&#39;用于HAVING子句

我尝试过在这里搜索,但我发现的所有问题都是通过将过滤器从HAVING移到WHERE来解决的,这可以做到,因为这些案例实际上并非如此包括一个聚合函数。但是,就我而言,确实如此,我认为这正是HAVING的用途?即我想过滤掉报告期内没有任何小时数的所有行。

我可以解决&#34;它不是引用Total report hours而是重复整个SUM,而不是这样:

HAVING
    SUM(CASE WHEN report.date BETWEEN :report_start AND :report_end THEN report.hours END) != 0

但是当它已经计算好并且(从我的观点来看)在查询本身可用时,感觉非常不必要和混乱。

那么,有没有一种方法可以表达这一点,它可以在严格模式下工作,而 重复自己?

3 个答案:

答案 0 :(得分:0)

在某些数据库中,您需要复制聚合表达式:

SELECT p.id as 'Project code',
       SUM(r.hours) as 'Total hours',
       SUM(CASE WHEN r.date BETWEEN :report_start AND :report_end THEN r.hours END) as 'Total report hours'
FROM report r INNER JOIN
     project p
     ON p.id = r.id
WHERE r.date <= :report_end
GROUP BY p.id
HAVING SUM(CASE WHEN r.date BETWEEN :report_start AND :report_end THEN r.hours END) <> 0;

我建议你不要使用单引号作为列别名。您正在使用多个数据库,因此不清楚哪个转义字符最好 - 反引号,双引号或方括号。

当然,您也可以使用子查询。

答案 1 :(得分:0)

将您的查询包装在派生表中。在顶级添加条件:

select *
from
(
SELECT
    project.id
        'Project code',
    SUM(report.hours)
        'Total hours',
    SUM(CASE WHEN report.date BETWEEN :report_start AND :report_end THEN report.hours END)
        'Total report hours'

FROM report
    INNER JOIN project ON project.id = report.id
WHERE report.date <= :report_end

GROUP BY
    project.id
) dt
WHERE `Total report hours` != 0

答案 2 :(得分:0)

我不知道MySQL MariaDB 10.2的哪个版本,但是至少在MySQL中,这是一个错误。它已在MySQL 5.7.5中修复。

MySQL manual甚至提到了这一点:

  

从MySQL 5.7.5开始,默认的SQL模式包括ONLY_FULL_GROUP_BY。 (在5.7.5之前,MySQL不会检测到功能依赖性,并且默认情况下未启用ONLY_FULL_GROUP_BY。