你可能会问的第一个问题是,SO上有多少Group by / Order by Questions?很多。这些都不符合我的具体情况。这是我的以下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有2个项目6小时前和2天前,团队C有一个9小时前的媒体项目。
如果选择的顺序是团队A,C,B,那么媒体项目将如下...
可能会有一些愚蠢的评论说
按队名虚拟订购!这么简单的问题。 (这个答案将获得约+4票)
但这显然对我毫无帮助。我不知道哪些团队会有最佳订单(如果有任何自然或不自然的订单甚至可以使用超过3个案例)。有没有这样的方法,我可以在1个SQL查询中执行此操作。我听说循环中的MySQL是一个糟糕的决定,因此我希望它在1个SQL调用中工作。
答案 0 :(得分:6)
这种查询通常被标记为“每组最大n个”以供将来参考。
您希望每个团队的最长时间和对应的列,对吗?
解决此问题的典型方法是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_uid
(GROUP BY
变量),以及M.time < M2.time
(变量)我们想要MAX。)。LEFT JOIN
,如果有一个M.time,其中没有更大的 M2.time(对于同一个团队),则M2.time将为NULL。这正是当M.time是该团队的最长时间时。M2.time IS NULL
条件中添加WHERE
(以强制执行上述操作)GROUP BY
,ORDER BY
(在加入条件中处理)。