【问题标题】:MySQL, GroupBy OrderByMySQL, GroupBy OrderBy
【发布时间】:2012-02-21 23:29:40
【问题描述】:

您可能会问的第一个问题是 SO 上有多少 Group by / Order by 问题?很多。这些都不适合我的具体情况。这是我的以下 SQL 查询。

目标是在$teamArr(一组唯一ID)中获取每个团队的最新媒体。

我面临的问题是它不会为每个人获取最新的媒体,而是基于组的顺序,即媒体独立于团队的时间。

这里是 MySQL 命令(使用 PHP 的 sprintf() 命令,以便与团队 ID 一起使用)。

sprintf("SELECT M.*, T.name, T.has_image
    FROM media AS M
        JOIN teams AS T
          ON T.team_uid = M.team_uid
    WHERE M.team_uid IN (%s)
    GROUP BY T.team_uid
    ORDER BY M.time DESC", implode(", ", $teamArr));

场景:

团队 A 有 3 小时前的媒体项目,团队 B 有 6 小时前和 2 天前的媒体项目,团队 C 有 9 小时前的媒体项目。

如果选择的顺序是Team A、C、B,那么媒体项将如下...

  • TeamA 3 小时前的媒体项目
  • TeamC 9 小时前的媒体项目
  • TeamB 2 天前的媒体项目

可能会有一些愚蠢的言论说

只需按团队名称订购即可!这么简单的问题。 (这个答案将获得大约 +4 票)

但这显然对我没有帮助。我不知道哪些团队将拥有最佳顺序(如果任何自然或非自然顺序甚至可以处理超过 3 个案例)。有没有一种方法可以让我在 1 个 SQL 查询中做到这一点。我听说循环中的 MySQL 是一个糟糕的决定,因此我希望它在 1 个 SQL 调用中工作。

【问题讨论】:

  • 不,这在 SQL 中不是一件容易的事。虽然它通常被问到。通常足以拥有自己的标签:[greatest-n-per-group]。通过单击右侧相关标题上方或下方的该标签进行搜索。
  • 你能把 2 天变成 48 小时而不是几天,这样你就可以对所有人使用相同的比较了吗?
  • 它是一个 unix 时间戳@northpole。所以比较无关紧要......它只是一个场景,所以你可以看到发生了什么......
  • 好的,我没有其他建议,所以我对解决方案非常感兴趣......我会看的。
  • 您不想通过M.time 订购,但您只想汇总每个组成员的最新信息。请参阅aggregate functions 并暂时删除 order by 子句。如果您仍然需要它,您可以稍后再次添加它。

标签: php mysql group-by sql-order-by greatest-n-per-group


【解决方案1】:

这种查询通常被标记为“greatest-n-per-group”以供将来参考。

您想要每个团队的最大时间相应的列,对吧?

解决这个问题的典型方法是 LEFT JOIN 表你想获得最大值的表(在你的情况下是 media):

SELECT M.*, T.name, T.has_image
FROM media AS M
LEFT JOIN media AS M2              -- new: join media to itself
       ON M.team_uid = M2.team_uid -- within each team_uid (GROUP BY var)
      AND M.time < M2.time         -- and a sort on time (ORDER BY var)
JOIN teams AS T              -- same as before.
 ON T.team_uid = M.team_uid
WHERE M.team_uid IN (%s)     
  AND M2.time IS NULL        -- new: this selects the MAX M.time for each team.

变化:

  • LEFT JOIN media 到它自己每个team_uidGROUP BY 变量),这样M.time &lt; M2.time(我们想要最大的变量)。
  • 因为它是LEFT JOIN,如果有一个M.time 没有更大的 M2.time(对于同一个团队),那么M2.time 将为NULL。这正是 M.time 是该团队的 MAX 时间的时候。
  • WHERE 条件中添加M2.time IS NULL(以强制执行上述)
  • 去掉GROUP BYORDER BY(在join条件下处理)。

【讨论】:

  • 让我试试这个。我已经开始做一些阅读了。我从未听说过greatest-n-per-group problem,但现在我至少可以开始搜索了!
  • 据我所知,这工作正常。我非常感谢您提供的代码,但更感谢您的解释。如果我理解代码背后的原因,它会让编码变得更好!
  • 不用担心 - 当你第一次这样做时,这种查询会令人困惑,但如果你只尝试使用 media 表(暂时忘记加入 teams)并查看连接没有应用任何WHERE 条件的表格,即SELECT .., M.time, M2.time FROM M LEFT JOIN M2 ON.. 没有 IS NULL,它可能很有教育意义。
猜你喜欢
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多