Mic*_*ael 4 php mysql group-by sql-order-by greatest-n-per-group
您可能会问的第一个问题是,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));
Run Code Online (Sandbox Code Playgroud)
场景:
A队有一个3小时前的媒体项目,B队有2个项目6小时前和2天前,而C队有一个9小时前的媒体项目.
如果选择的顺序结果是团队A,C,B那么媒体项目将如下...
可能会有一些愚蠢的评论说
只需按团队名称命名!这么简单的问题.(这个答案将获得约+4票)
但这显然对我毫无帮助.我不知道哪些团队会有最佳订单(如果有任何自然或不自然的订单甚至可以使用超过3个案例).有没有这样的方法,我可以在1个SQL查询中执行此操作.我听说循环中的MySQL是一个糟糕的决定,因此我希望它在1个SQL调用中工作.
这种查询通常被标记为"每组最大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.
Run Code Online (Sandbox Code Playgroud)
变化:
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(在连接条件中处理).