给出一个这样的表:
id; day; daily
1; 2013-07-01; 50.00
1; 2013-07-02; 60.00
1; 2013-07-03; 70.00
1; 2013-07-04; 80.00
此查询:
SELECT
id
day,
daily,
SUM(daily) total
FROM
table
GROUP BY
id
ORDER BY
day DESC
返回:
1; 2013-07-04; 80.00; 260.00
到目前为止一切都很好。
我的问题是:依靠order by语句对所有“未发表的”值是否安全?我需要确保我读取具有最高日期的行的“每日”的值。
谢谢,
彼得
PS我发现了几个处理类似问题的线程,但是他们都使用了子查询,这在我的情况下是没有选择的。
答案 0 :(得分:4)
不,依靠这个绝对不安全。事实上,这种结构在逻辑上毫无意义(it is invalid SQL),并且MySql仍然允许你这样做的事实是......糟糕的。以下是手册的摘录:
但是,这主要适用于每个中的所有值 GROUP BY中未命名的非聚合列对于每个列都是相同的 组。 服务器可以自由选择每个组中的任何值,所以 除非它们相同,否则所选择的值是不确定的。 此外,不能从每个组中选择值 受添加ORDER BY子句的影响。对结果集进行排序 选择值后发生,ORDER BY不影响 服务器选择的每个组中的值。
如果你想获得最后一行和一个总和,那么只需使用两个单独的查询:一个用于最后一行,一个用于总和。
答案 1 :(得分:0)
您的查询完全没问题。它只是没有你想要的东西:
SELECT id, day, daily, SUM(daily) total
FROM table
GROUP BY id
ORDER BY day DESC;
字段day
和daily
取自数据中的任意行。在分组后,ORDER BY
处理。执行所需操作的正确方法是使用子查询,或使用以下group_concat()
/ substring_index()
方法:
SELECT id, max(day) as day,
substring_index(group_concat(daily order by day desc), ',', 1) as daily,
SUM(daily) as total
FROM table
GROUP BY id
ORDER BY day DESC;
这会将daily
变成一个字符串。如果您想将其作为数字,请将其转换回来。