如何在SQL中选择条件值为一列的行

如何在SQL中选择条件值为一列的行,sql,Sql,假设我有这张桌子: id timeline ---|--------| 1 | BASELINE | 1 | MIDTIME | 1 | ENDTIME | 2 | BASELINE | 2 | MIDTIME | 3 | BASELINE | 4 | BASELINE | 5 | BASELINE | 5 | MIDTIME | 5 | ENDTIME | 6 | MIDTIME | 6 | ENDTIME | 7 | RISK

假设我有这张桌子:

id  timeline   
---|--------|
 1 | BASELINE |
 1 | MIDTIME  |
 1 | ENDTIME  | 
 2 | BASELINE |
 2 | MIDTIME  | 
 3 | BASELINE | 
 4 | BASELINE | 
 5 | BASELINE | 
 5 | MIDTIME  | 
 5 | ENDTIME  | 
 6 | MIDTIME  | 
 6 | ENDTIME  |
 7 | RISK     | 
 7 | RISK     |    
这就是数据的样子,除了数据有更多的观测值(几千个)

如何获得输出,使其看起来像这样:

id  timeline   
---|--------|
 1 | BASELINE |
 1 | MIDTIME  |
 2 | BASELINE |
 2 | MIDTIME  | 
 5 | BASELINE | 
 5 | MIDTIME  |
我如何选择每个ID的前两个术语,它们有两个特定的时间轴值(基线和中间时间)?注意,ID6有中间时间和结束时间,ID7有两个风险,我不想要这两个id

我曾经

SELECT * 
FROM df 
WHERE id IN (SELECT id FROM df GROUP BY id HAVING COUNT(*)=2)
并且得到了具有两个时间线值(下面的输出)的ID,但不知道如何获得只有基线和中间时间的行

id  timeline   
---|--------|
 1 | BASELINE |
 1 | MIDTIME  |
 2 | BASELINE |
 2 | MIDTIME  | 
 5 | BASELINE | 
 5 | MIDTIME  |
 6 | MIDTIME  |    ---- dont want this
 6 | ENDTIME  |    ---- dont want this
 7 | RISK     |    ---- dont want this
 7 | RISK     |    ---- dont want this

非常感谢。

您可以尝试使用exists-

    select * from t t1 where timeline in ('BASELINE','MIDTIME') and
    exists
     (select 1 from t t2 where t1.id=t2.id and timeline in ('BASELINE','MIDTIME')
            group by t2.id having count(distinct timeline)=2)
输出:

id  timeline
1   BASELINE
1   MIDTIME
2   BASELINE
2   MIDTIME
5   BASELINE
5   MIDTIME

我想这个查询应该会给出你想要的结果

注意:据我所知,您不希望ID存在“ENDTIME”,并且在示例数据中,ID 1有一个“ENDTIME”。我假设这是一个错误,所以我做了一个查询,排除了所有包含“ENDTIME”的id


可能有很多方法可以做到这一点,这里有一种方法可以在只有基线行和中间行的情况下提取基线行和中间行,确保每个返回的ID只有2行。如果不知道时间线的顺序,就不可能再进一步我不认为:

SELECT
      id
    , timeline
FROM (
    SELECT
          *
        , SUM(CASE WHEN timeline = 'BASELINE' THEN 1 ELSE 0 END) OVER (PARTITION BY id) AS BaselineCount
        , SUM(CASE WHEN timeline = 'MIDTIME' THEN 1 ELSE 0 END) OVER (PARTITION BY id) AS MidtimeCount
    FROM df
    WHERE df.timeline IN ('BASELINE', 'MIDTIME')
) subquery
WHERE subquery.BaselineCount > 0
AND subquery.MidtimeCount > 0
GROUP BY
      id
    , timeline
;

您使用的是哪种SQL引擎?实际上我在R中使用SQL包。另外,前两个时间线值是否需要是基线和中间时间?如果是,您如何排列时间线值?是的。需要为基线和MidtimeID 1的两个值有3个值,并且只需要具有基线和MIDTIME的那2个值。因此,您只想排除ID 6以获得该值吗?ID 6是最后一个ID(最大值)?如果是这样的话,很容易修复它。如果没有,您应该为exlcude ID提供更多的条件,而不是“ENDTIME”值。好的,我想我会添加更多来澄清。明白了,定义哪些是带来记录或排除记录的所有标准。例如:如果一个ID有基线、中间时间和结束时间,那么应该带BASE和MID,而不是END。如果ID只有MIDTIME和ENDTIME,则不应包括在内。更新了修复错误的答案
BaselineCount=sum(…)
是无效的标准SQL(除非表中有一列名为
BaselineCount
)@Iwishworldpeace,很高兴它帮助了你:)
SELECT
      id
    , timeline
FROM (
    SELECT
          *
        , SUM(CASE WHEN timeline = 'BASELINE' THEN 1 ELSE 0 END) OVER (PARTITION BY id) AS BaselineCount
        , SUM(CASE WHEN timeline = 'MIDTIME' THEN 1 ELSE 0 END) OVER (PARTITION BY id) AS MidtimeCount
    FROM df
    WHERE df.timeline IN ('BASELINE', 'MIDTIME')
) subquery
WHERE subquery.BaselineCount > 0
AND subquery.MidtimeCount > 0
GROUP BY
      id
    , timeline
;