简体   繁体   English

SQL查询选择多个行,其中'field'等于'value',然后添加与结果关联的其他id

[英]SQL query select multiple rows where 'field' equals to 'value' then add the other ids associated with the result

I have a users table that contains persons and their status. 我有一个包含人员及其状态的users表。 The ID field is not unique. 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

In this case, I want to get the Users that are online and all the other same ids of the user in this table to form like this. 在这种情况下,我想让在线的用户和此表中用户的所有其他相同的ID形成这样的形式。

ID | Name | Status
1  | Jon  | Online
1  | Jon  | Online
1  | Jon  | NULL
3  | Kim  | Online
3  | Kim  | NULL

Is there a way to get this result with one select statement? 有没有办法用一个select语句获得这个结果?

Without a login timestamp, it doesn't give you much information of how you want to get the most recent event for a person. 如果没有登录时间戳,它不会为您提供有关如何为某人获取最新事件的详细信息。 If they can have 3 rows, how do you know which one means they ARE online and which one means they WERE online. 如果他们可以有3行,你怎么知道哪一个意味着他们在线,哪一个意味着他们在线。

http://sqlfiddle.com/#!6/3833e/4 <<< MS SQL Setup http://sqlfiddle.com/#!6/3833e/4 <<< MS SQL安装程序

http://sqlfiddle.com/#!4/f190f/2 <<< Oracle SQL Setup http://sqlfiddle.com/#!4/f190f/2 <<< Oracle SQL安装程序

The Fiddle gives you the people in descending order of most recent login grouped by person. Fiddle以按人员分组的最近登录的降序为您提供给人。 If you only want to grab the most recent logins, use the second select on the SQL side. 如果您只想获取最新的登录信息,请使用SQL端的第二个选择。

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

There are a couple ways to do this -- one is to use exists : 有几种方法可以做到这一点 - 一种是使用exists

select id, name, status
from users u
where exists (
    select 1
    from users u2 
    where u.id = u2.id and u2.status = 'Online'
    )

Here's a version using in (although I prefer the prior): 下面是使用一个版本in (虽然我更喜欢前):

select id, name, status
from users
where id in (
    select id
    from users 
    where status = 'Online'
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM