构建此查询的最佳方法是什么?

时间:2010-04-17 22:23:55

标签: sql mysql greatest-n-per-group

  

可能重复:
  Retrieving the last record in each group

我有两个类似于此的设置表(简化为任务):

动作 -

id - user_id - action - time

用户 -

id - name

我想为每个用户输出最新动作。我不知道该怎么做。

我对SQL不太满意,但从我查看的内容来看,它看起来应该如下所示。但不确定。

SELECT `users`.`name`, *
FROM users, actions
JOIN < not sure what to put here >
ORDER BY `actions`.`time` DESC
< only one per user_id >

任何帮助都将不胜感激。

6 个答案:

答案 0 :(得分:1)

SELECT * FROM users JOIN actions ON actions.id=(SELECT id FROM actions WHERE user_id=users.id ORDER BY time DESC LIMIT 1);

答案 1 :(得分:1)

您需要最大限度地进行分组 - 请参阅此处的示例http://jan.kneschke.de/projects/mysql/groupwise-max/

这是我为其他人做的一个例子,它类似于你的要求:

http://pastie.org/925108

select
 u.user_id,
 u.username,
 latest.comment_id
from
 users u
left outer join
(
  select
   max(comment_id) as comment_id,
   user_id
  from
   user_comment
  group by
   user_id
 ) latest on u.user_id = latest.user_id;

答案 2 :(得分:0)

选择u.name,a.action,a.time
来自用户u,行动a
其中u.id = a.user_id
和a.time in(从user_id = u.user_id group by user_id的action中选择max(time))



注意未经测试 - 但这应该是模式

答案 3 :(得分:0)

DECLARE @Table (ID Int, User_ID, Time DateTime)

-- This gets the latest entry for each user
INSERT INTO @Table (ID, User_ID, Time)
SELECT ID, User_ID, MAX(TIME)
FROM actions z
INNER JOIN users x on x.ID = z.ID
GROUP BY z. userID

-- Join to get resulting action
SELECT z.user_ID, z.Action
FROM actions z 
INNER JOIN @Table x on x.ID = z.ID

答案 4 :(得分:0)

这是Stack Overflow上经常出现的最大n组问题。关于这个问题,请关注其他几十个帖子的标签。

如果您的架构没有子查询且没有GROUP BY,这里是如何在MySQL中执行的:

SELECT u.*, a1.*
FROM users u JOIN actions a1 ON (u.id = a1.user_id)
LEFT OUTER JOIN actions a2 ON (u.id = a2.user_id AND a1.time < a2.time)
WHERE a2.id IS NULL;

换句话说,向用户显示她的操作,这样如果我们搜索具有相同用户和稍后时间的其他操作,我们就找不到。

答案 5 :(得分:0)

在我看来,以下将是有效的

WITH GetMaxTimePerUser (user_id, time) (
    SELECT user_id, MAX(time)
    FROM actions
    GROUP BY user_id
)
SELECT u.name, a.action, amax.time
FROM actions AS a
    INNER JOIN users AS u ON u.id=a.user_id
    INNER JOIN GetMaxTimePerUser AS u_maxtime ON u_maxtime.user_id=u.id
WHERE a.time=u_maxtime.time

在没有子查询和OUTER JOIN的情况下使用临时命名结果集(公用表表达式或CTE)是最适合查询优化的方法。 (CTE类似于VIEW,但仅存在虚拟或内联)