根据另一列的值过滤一列

时间:2017-09-28 15:27:21

标签: sql sql-server

假设我有一个表TestTable,它看起来像这样:

|-------------------|------------------|------------------|
|        Id         |    EventDate     |     EventCode    |
|-------------------|------------------|------------------|
|         1         |    2017-04-10    |        42        |
|-------------------|------------------|------------------|
|         2         |    2017-10-32    |        50        |
|-------------------|------------------|------------------|
|         3         |    2017-06-15    |        60        |
|-------------------|------------------|------------------|
|         4         |    2017-07-13    |        10        |
|-------------------|------------------|------------------|

我想只选择比EventCode 60更晚发生的事件。显然,我可以创建一个临时变量并使用WHERE子句:

DECLARE @TestEventDate DATETIME;
SET @TestEventDate = 
    (SELECT TOP 1 EventDate
    FROM TestTable
    WHERE EventCode = 60);
SELECT *
FROM TestTable
WHERE EventDate > @TestEventDate

但我不禁想到,如果不运行多个SELECT语句,这应该是一种方法。我可以在同一个SELECT中间接过滤,将EventDate映射到where子句中的EventCode而不设置临时变量吗?

以上是临时表的设置,以便您可以直接在SSMS中运行它:

DECLARE @TestTable TABLE(Id INT, EventDate DATETIME, EventCode INT);
INSERT INTO @TestTable(Id, EventDate, EventCode) VALUES (1, '20170410', 42);
INSERT INTO @TestTable(Id, EventDate, EventCode) VALUES (2, '20171030', 50);
INSERT INTO @TestTable(Id, EventDate, EventCode) VALUES (3, '20170615', 60);
INSERT INTO @TestTable(Id, EventDate, EventCode) VALUES (4, '20170713', 10);

DECLARE @TestEventDate DATETIME;
SET @TestEventDate = 
    (SELECT TOP 1 EventDate
    FROM @TestTable
    WHERE EventCode = 60);
SELECT *
FROM @TestTable
WHERE EventDate > @TestEventDate

3 个答案:

答案 0 :(得分:2)

如果EventCode是唯一的,您可以执行以下操作:

SELECT T2.*
FROM TestTable AS T
INNER JOIN TestTable AS T2 ON (T.eventdate > T2.eventdate)
WHERE T.EventCode = 60

答案 1 :(得分:1)

可以在联接中完成整个事情。基本上,您希望将符合描述的所有记录加入到您想要的记录中:

DECLARE @TestTable TABLE(Id INT, EventDate DATETIME, EventCode INT);

INSERT INTO @TestTable
    (Id,  EventDate, EventCode) 
VALUES 
    ( 1, '20170410',        42),
    ( 2, '20171030',        50),
    ( 3, '20170615',        60),
    ( 4, '20170713',        10);   

SELECT
    T1.*
FROM
    @TestTable T1
    JOIN @TestTable T2
        ON T1.EventDate > T2.EventDate
        AND T2.EventCode = 60

答案 2 :(得分:0)

一种方法是子查询:

SELECT *
FROM TestTable
WHERE EventDate > (SELECT TOP 1 EventDate FROM TestTable WHERE EventCode = 60);

你也可以使用窗口函数:

select tt.*
from (select tt.*,
             max(case when eventcode = 60 then eventdate end) over () as eventdate_60
      from testtable tt
     ) tt
where eventdate > eventdate_60;