我有一个带有“users”的Oracle表,以及一个包含与用户相关的“事件”的表,并在每个事件发生时加盖日期戳。我想制作一个简单的表格,显示每个用户和发生的最新事件,但我无法完成嵌套查询或聚合功能,因为我是没有聚合我想要的列。如果我只是希望MAX(event_date)
相当简单,但我想要event_status where MAX(event_date)
之类的东西。我敢肯定,如果不诉诸程序就可以做到,但我无法解决这个问题。有人有解决方案吗?
user_id user_name
1 bob
2 sally
3 fred
event_id user_id event_date event_status
1 1 3/1/15 hired
2 1 3/2/15 active
3 3 4/1/15 hired
4 3 4/3/15 on leave
5 2 3/3/15 hired
6 2 4/1/15 on leave
7 2 5/1/15 active
期望的结果:
user_name current_status
bob active
sally active
fred on leave
答案 0 :(得分:1)
使用相关子查询可能最简单:
select u.*,
(select e.status
from events e
where e.user_id = u.user_id
order by e.event_date desc
limit 1
) as Most_Recent_Status
from users u;
这节省了聚合(或等效select distinct
)的麻烦,这在某些数据库中相当昂贵。请注意,这使用MySQL / Postgres LIMIT 1
作为子查询。其他数据库具有类似的功能。
编辑:
select u.*,
(select max(e.status) keep (dense_rank first order by event_date desc)
from events e
where e.user_id = u.user_id
) as Most_Recent_Status
from users u;
答案 1 :(得分:0)
主要思想是为每个用户选择最新事件,然后连接表:
select a.user_name, b.event_status
from
users as a
inner join
events as b
on (a.user_id = b.user_id)
inner join
(
select user_id, max(event_id) as event_id
from table2
group by user_id
) as q
on (b.user_id = q.user_id and b.event_id = q.event_id)
答案 2 :(得分:0)
这是一个SQL查询:
select U.user_name,
E.event_status
from users U,
events E
where U.user_id = E.user_id
and (E.user_id, E.event_date) = (select distinct user_id,
max(event_date)
from events
where user_id = E.user_id group by user_id
)
答案 3 :(得分:0)
使用SQL Server 2014测试,YMMV测试其他数据库
(请适当更改列和表的名称。)
简短回答
SELECT
username, eventstatus
FROM
(
SELECT
u.username,
e.eventstatus,
ROW_NUMBER() OVER (PARTITION BY u.username ORDER BY e.eventdate DESC) RowNum
FROM @userTable u JOIN @eventTable e ON u.userid=e.userid
) sub
WHERE sub.RowNum = 1
长时间测试
DECLARE @userTable TABLE (userid INT, username VARCHAR(50))
DECLARE @eventTable TABLE (eventid INT, userid INT, eventdate DATETIME, eventstatus VARCHAR(20))
INSERT INTO @userTable VALUES (1, 'bob')
INSERT INTO @userTable VALUES (2, 'sally')
INSERT INTO @userTable VALUES (3, 'fred')
INSERT INTO @eventTable VALUES (1, 1, '3/1/15', 'hired')
INSERT INTO @eventTable VALUES (2, 1, '3/2/15', 'active')
INSERT INTO @eventTable VALUES (3, 3, '4/1/15', 'hired')
INSERT INTO @eventTable VALUES (4, 3, '4/3/15', 'on leave')
INSERT INTO @eventTable VALUES (5, 2, '3/3/15', 'hired')
INSERT INTO @eventTable VALUES (6, 2, '4/1/15', 'on leave')
INSERT INTO @eventTable VALUES (7, 2, '5/1/15', 'active')
SELECT
username, eventstatus
FROM
(
SELECT
u.username,
e.eventstatus,
ROW_NUMBER() OVER (PARTITION BY u.username ORDER BY e.eventdate DESC) RowNum
FROM @userTable u JOIN @eventTable e ON u.userid=e.userid
) sub
WHERE sub.RowNum = 1