我有一个users
表,其中包含人员及其状态。ID字段不是唯一的。
ID | Name | Status
1 | Jon | Online
2 | Ken | Away
3 | Kim | Online
4 | Van | Offline
1 | Jon | NULL
2 | Ken | NULL
3 | Kim | NULL
4 | Van | NULL
1 | Jon | Online
在这种情况下,我想让在线的用户和该表中用户的所有其他相同id形成这样的形式。
ID | Name | Status
1 | Jon | Online
1 | Jon | Online
1 | Jon | NULL
3 | Kim | Online
3 | Kim | NULL
有没有一种方法可以用一个select语句得到这个结果?
如果没有登录时间戳,它不会为您提供太多关于如何获取个人最近事件的信息。如果他们可以有3行,你怎么知道哪一行意味着他们在线,哪一行代表他们在线。
http://sqlfiddle.com/#!6/3833e/4<lt<MS SQL安装
http://sqlfiddle.com/#!4/f190f/2<lt<Oracle SQL安装
Fiddle会按最近登录次数的降序按人员分组。如果只想获取最近的登录信息,请使用SQL端的第二个select。
SELECT t1.ID
, t1.Name
, t1.Status
, t1.OnlineTimeStamp
, ROW_NUMBER() OVER ( PARTITION BY t1.ID ORDER BY t1.OnlineTimeStamp DESC ) AS rn
FROM Test_Client t1
WHERE EXISTS ( SELECT 1 FROM Test_Client t2 WHERE t2.ID = t1.ID AND t2.Status = 'Online' )
ORDER BY t1.ID, rn
;
SELECT tcSub.ID
, tcSub.Name
, tcSub.Status
FROM (
SELECT t1.ID
, t1.Name
, t1.Status
, t1.OnlineTimeStamp
, ROW_NUMBER() OVER ( PARTITION BY t1.ID ORDER BY t1.OnlineTimeStamp DESC ) AS rn
FROM Test_Client t1
WHERE EXISTS ( SELECT 1 FROM Test_Client t2 WHERE t2.ID = t1.ID AND t2.Status = 'Online' )
) tcSub
WHERE tcSub.rn = 1
ORDER BY tcSub.ID
有两种方法可以做到这一点——一种是使用exists
:
select id, name, status
from users u
where exists (
select 1
from users u2
where u.id = u2.id and u2.status = 'Online'
)
这里有一个使用in
的版本(尽管我更喜欢以前的版本):
select id, name, status
from users
where id in (
select id
from users
where status = 'Online'
)