我首先遇到以下问题的问题是group by
子句是在order by
之前执行的:
saved.recipe_id
列是由UNIX_TIMESTAMP()
生成的整数
SELECT
saved.recipe_id,
saved.`date`,
user.user_id
FROM saved
JOIN user
ON user.id = saved.user_id
GROUP BY saved.recipe_id
ORDER BY saved.`date` DESC
所以我尝试了各种不同的可能解决方案,包括子查询和其他bs。最后,我最终在join
子句中尝试了一些不同的子查询,这要求我将表顺序从from
子句更改为join
子句。我决定尝试以下方法:
SELECT
saved.recipe_id,
saved.`date`,
user.user_id
FROM user
JOIN saved
ON user.id = saved.user_id
GROUP BY saved.recipe_id
ORDER BY saved.`date` DESC
出于某种原因,这似乎是正确的顺序,但为什么?
这个更改怎么能让我的查询排序更准确呢?
真的吗?或者它只是碰巧为我提出的测试案例做了吗?
答案 0 :(得分:8)
所以我第一次遇到以下问题的问题是该组 by子句在订单之前执行:
这不是问题。这就是SQL的定义方式及其运作方式。 group by
创建一组新行,order by
命令这些行。
此处没有订购问题。有一个“理解SQL”的问题。您的order by
仅排序查询结果。这些结果由group by
产生,连接的顺序与结果无关。
您使用的是名为Hidden Columns的MySQL扩展程序。这是当您的聚合查询包含select
(或having
或order by
子句)中不属于聚合函数(sum()
等)或group by
的一部分。以下是documentation:
MySQL扩展了GROUP BY的使用,以便选择列表可以引用 未在GROUP BY子句中命名的非聚合列。这意味着 前面的查询在MySQL中是合法的。您可以使用此功能 通过避免不必要的列排序来获得更好的性能 分组。但是,这主要适用于每个中的所有值 GROUP BY中未命名的非聚合列对于每个列都是相同的 组。服务器可以自由选择每个组中的任何值,所以 除非它们相同,否则所选择的值是不确定的。 此外,不能从每个组中选择值 受添加ORDER BY子句的影响。对结果集进行排序 选择值后发生,ORDER BY不影响 服务器选择的每个组中的值。
据推测,您希望获得与之相关的最新日期和用户。以下查询正确且一致地执行您想要的操作:
SELECT saved.recipe_id, max(saved.`date`) as MostRecentDate,
substring_index(group_concat(user.user_id), ',', 1) as MostRecentUser
FROM user JOIN
saved
ON user.id = saved.user_id
GROUP BY saved.recipe_id
ORDER BY max(saved.`date`) DESC;
答案 1 :(得分:2)
根据我的记忆,GROUP BY始终在ORDER BY之前执行。如果检索任何不在任何聚合函数中的列,则该列的结果将是随机的。第二次查询的正确顺序是偶然的。
相反saved.date
使用MAX(saved.date)
然后,您将从每个单一组中获得确定的顺序,然后您将订购确定的结果。