MySQL 5.7 | GROUP BY |非聚合列错误

时间:2017-06-15 15:28:33

标签: mysql sql

我将我们的mysql数据库从5.6升级到5.7,并且正在修复一些抛出一些错误的查询。我正在处理的一个查询涉及带有COALESCE的GROUP BY。

这是有效的查询(抽象):

SELECT 
    MAX(a.id),
    a.entered,
    count(*) AS teh_count
FROM
    a
INNER JOIN
    b ON b.id = a.link_to_b_id
INNER JOIN
    c ON c.link_to_b_id = b.id
WHERE
    b.revision_id > 0
AND
    c.terminated_at = '0000-00-00 00:00:00'
AND
    a.created_at > date_sub(NOW(), INTERVAL 8 HOUR)
GROUP BY
    a.entered
ORDER BY
    teh_count DESC
LIMIT
    6;

但我需要使用c.override进行COALESCE,所以我尝试了以下内容:

SELECT 
    MAX(a.id),
    a.entered,
    COALESCE(c.override, a.entered) AS appearance,
    count(*) AS teh_count
FROM
    a
INNER JOIN
    b ON b.id = a.link_to_b_id
INNER JOIN
    c ON c.link_link_to_b_id = b.id
WHERE
    b.revision_id > 0
AND
    c.terminated_at = '0000-00-00 00:00:00'
AND
    a.created_at > date_sub(NOW(), INTERVAL 8 HOUR)
GROUP BY
    a.entered
ORDER BY
    teh_count DESC
LIMIT
    6;

但MySQL 5.7现在抛出以下错误:Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'st_core.tuc.code_appearance_override' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

我认为我可以更改sql_mode,但我也不愿意。错误告诉我的是有道理的,因为COALESCE列没有聚合,所以作为测试,我用MAX包裹它并且它有效,但是对我来说它看起来有点像hacky。

有更优雅的解决方案吗?

2 个答案:

答案 0 :(得分:2)

您还应该在a.entered条款中加入group by,以及错误说明的内容。虽然不确定为什么要按其他列a.code_entered分组?

您的查询应该是

SELECT 
    MAX(a.id),
    a.entered,
    COALESCE(c.override, a.entered) AS appearance,
    count(*) AS teh_count
FROM
    a
INNER JOIN
    b ON b.id = a.link_to_b_id
INNER JOIN
    c ON c.link_link_to_b_id = b.id
WHERE
    b.revision_id > 0
AND
    c.terminated_at = '0000-00-00 00:00:00'
AND
    a.created_at > date_sub(NOW(), INTERVAL 8 HOUR)
GROUP BY
    a.entered,
    COALESCE(c.override, a.entered)
ORDER BY
    teh_count DESC
LIMIT
    6;

答案 1 :(得分:2)

我想你想要这样的事情:

SELECT MAX(a.id),
       COALESCE(c.override, a.entered) AS appearance,
       count(*) AS the_count
FROM a INNER JOIN
     b
     ON b.id = a.link_to_b_id INNER JOIN
     c
     ON c.link_link_to_b_id = b.id
WHERE b.revision_id > 0 AND
      c.terminated_at = '0000-00-00 00:00:00' AND
      a.created_at > date_sub(NOW(), INTERVAL 8 HOUR)
GROUP BY appearance
ORDER BY the_count DESC
LIMIT 6;

这会从a.entered列表中删除SELECT,因此只有一列用于分组。该列可以由GROUP BY中的表别名引用。