如何在GROUP BY子句上使用别名?

时间:2016-09-06 22:32:37

标签: mysql sql group-by

这是我的问题:

SELECT  SUM(score) score,
    type,
    context,
    post_id,
    e.table_code,
    comment_id,
    MIN(seen) seen,
    MAX(date_time) d_t,
    (CASE   WHEN FROM_UNIXTIME(MAX(date_time)) >= CURDATE() THEN 'today'
        WHEN FROM_UNIXTIME(MAX(date_time)) >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) THEN 'yesterday'
        WHEN FROM_UNIXTIME(MAX(date_time)) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) THEN 'in last week'
        ELSE 'in last month'
    END) as range_day
FROM `events` e
WHERE e.id IN ($ids)
GROUP BY type, post_id, e.table_code, comment_id, range_day
ORDER BY seen, MAX(date_time) desc, MAX(e.id) desc

它抛出了这个错误:

  

# 1056 - 无法在'range_day'上分组

如果我从range_day子句删除GROUP BY,那么它也可以。但我还需要根据range_day对结果进行分组。我怎么能这样做?

3 个答案:

答案 0 :(得分:3)

不确定你要做什么。但是您可以将查询包装到GROUP BY子句中没有range_day的子查询中。然后按原样使用外部查询中的GROUP BY子句。

SELECT  SUM(score) score,
    type,
    context, -- WARNING! Not listed in group by clause
    post_id,
    table_code,
    comment_id,
    MIN(seen) seen,
    MAX(d_t) d_t,
    range_day
FROM (
    SELECT  SUM(score) score,
        MAX(id) as id,
        type,
        context, -- WARNING! Not listed in group by clause
        post_id,
        e.table_code,
        comment_id,
        MIN(seen) seen,
        MAX(date_time) d_t,
        (CASE   WHEN FROM_UNIXTIME(MAX(date_time)) >= CURDATE() THEN 'today'
            WHEN FROM_UNIXTIME(MAX(date_time)) >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) THEN 'yesterday'
            WHEN FROM_UNIXTIME(MAX(date_time)) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) THEN 'in last week'
            ELSE 'in last month'
        END) as range_day
    FROM `events` e
    WHERE e.id IN ($ids)
    GROUP BY type, post_id, e.table_code, comment_id
) sub
GROUP BY type, post_id, table_code, comment_id, range_day
ORDER BY seen, MAX(d_t) desc, MAX(id) desc

但是 - 您选择context没有聚合,但未在GROUP BY子句中列出。因此,你会得到一些"随机"来自该组的价值。在严格模式下,查询将失败。

答案 1 :(得分:2)

您对range_day的定义并不完全有意义。为什么使用MAX()?什么是最大的?

使查询起作用的一种自然方法是从定义中删除MAX()

SELECT SUM(score) score, type, context, post_id, e.table_code, comment_id,
       MIN(seen) as seen, MAX(date_time) as d_t,
       (CASE WHEN FROM_UNIXTIME(date_time) >= CURDATE() THEN 'today'
             WHEN FROM_UNIXTIME(date_time) >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) THEN 'yesterday'
             WHEN FROM_UNIXTIME(date_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) THEN 'in last week'
            ELSE 'in last month'
        END) as range_day
FROM `events` e
WHERE e.id IN ($ids)
GROUP BY type, post_id, e.table_code, comment_id, range_day
ORDER BY seen, MAX(date_time) desc, MAX(e.id) desc;

更多评论:

  • IN ($ids)可能不符合您的期望。变量$ids被视为单个值,因此相当于e.di = $ids
  • 如果这不符合您的要求,那么您可能希望MAX()处于其他某个聚合级别。这将需要一个额外的子查询。

答案 2 :(得分:0)

首先,你的问题......

你不能GROUP BY聚合。请注意MAX()内的range_day。您的GROUP BY 包含SELECT中的所有非汇总项。 context缺失,可能导致后续版本中的错误。

然后是另一个问题......

         MIN(seen) seen,
         MAX(d_t) d_t,
...
ORDER BY seen,
         MAX(d_t) desc

注意不一致?含糊不清? seen(在ORDER BY)中应该是原始seen,还是别名seen,这意味着MIN(seen)?同上d_t

当您需要稍后引用别名时,请务必避免使用与列名相同的别名拼写。在WHERE中,它必须是列名;在ORDER BYHAVING中,它是别名。

所以,我认为,这是错误的:MAX(d_t) desc中的ORDER BY