JOIN,GROUP BY,ORDER BY

时间:2013-09-12 11:15:09

标签: mysql sql join group-by sql-order-by

我首先遇到以下问题的问题是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

出于某种原因,这似乎是正确的顺序,但为什么
这个更改怎么能让我的查询排序更准确呢? 真的吗?或者它只是碰巧为我提出的测试案例做了吗?

2 个答案:

答案 0 :(得分:8)

  

所以我第一次遇到以下问题的问题是该组   by子句在订单之前执行:

这不是问题。这就是SQL的定义方式及其运作方式。 group by创建一组新行,order by命令这些行。

此处没有订购问题。有一个“理解SQL”的问题。您的order by仅排序查询结果。这些结果由group by产生,连接的顺序与结果无关。

您使用的是名为Hidden Columns的MySQL扩展程序。这是当您的聚合查询包含select(或havingorder 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)

然后,您将从每个单一组中获得确定的顺序,然后您将订购确定的结果。