需要选择以下条件的Eid

时间:2017-07-13 15:06:01

标签: sql sql-server

需要选择Eid的最新状态为" Active"和活动状态生效日期必须为
 " 2013年5月4日" 并且相同的Eid应该满足以前的状态值" Inactive"和InActive状态生效日期必须为" 06-30-2007"

考虑下表:Emp

+-----+---------+----------+------------+
| EID |  ENAME  |  STATUS  | STATUSDATE |
+-----+---------+----------+------------+
| 101 | ABC.INC | INACTIVE | 06-30-2007 |
| 101 | ABC.INC | ACTIVE   | 05-04-2013 |
| 102 | DOC.LLC | ACTIVE   | 04-04-1997 |
| 102 | DOC.LLC | ACTIVE   | 04-04-1999 |
| 102 | DOC.LLC | INACTIVE | 04-04-2001 |
| 103 | XYZ.LLP | INACTIVE | 06-30-2007 |
| 103 | XYZ.LLP | ACTIVE   | 05-04-2009 |
| 103 | XYZ.LLP | ACTIVE   | 05-04-2013 |
+-----+---------+----------+------------+

此表中的EID" 101"拥有最新状态为" Active" statusdate为05-04-2013,它的立即上一状态为" InActive"同 状态日期为" 06-30-2007"。所以需要只有" 101"作为输出。

输出:

Eid
101 

1 个答案:

答案 0 :(得分:0)

我们将使用LAG函数获取statusdate排序的先前状态和statusdate,并按EID分区。因为这是一个窗口函数,并且窗口函数不能在where子句中,所以我们将其作为子查询然后应用过滤器。

SELECT
    [EID]
FROM (
    SELECT
        [EID]
        ,[STATUS]
        ,LAG([STATUS]) OVER (PARTITION BY [EID] ORDER BY [STATUSDATE]) AS [previous_status]
        ,LAG([STATUSDATE]) OVER (PARTITION BY [EID] ORDER BY [STATUSDATE]) AS [previous_status_date]
        ,[STATUSDATE]
    FROM @tbl
    ) AS tbl2
WHERE
    [STATUS] = 'ACTIVE'
    AND [STATUSDATE] = '05-04-2013'
    AND [previous_status] = 'INACTIVE'
    AND [previous_status_date] = '06-30-2007'

以下是用于测试的完整SQL:

DECLARE @tbl TABLE (
    [EID] INT
    ,[ENAME] VARCHAR(MAX)
    ,[STATUS] VARCHAR(MAX)
    ,[STATUSDATE] DATE
)

INSERT @tbl
VALUES
    (101,'ABC.INC','INACTIVE','6/30/2007')
    ,(101,'ABC.INC','ACTIVE','5/4/2013')
    ,(102,'DOC.LLC','ACTIVE','4/4/1997')
    ,(102,'DOC.LLC','ACTIVE','4/4/1999')
    ,(102,'DOC.LLC','INACTIVE','4/4/2001')
    ,(103,'XYZ.LLP','INACTIVE','6/30/2007')
    ,(103,'XYZ.LLP','ACTIVE','5/4/2009')
    ,(103,'XYZ.LLP','ACTIVE','5/4/2013')


SELECT
    [EID]
FROM (
    SELECT
        [EID]
        ,[STATUS]
        ,LAG([STATUS]) OVER (PARTITION BY [EID] ORDER BY [STATUSDATE]) AS [previous_status]
        ,LAG([STATUSDATE]) OVER (PARTITION BY [EID] ORDER BY [STATUSDATE]) AS [previous_status_date]
        ,[STATUSDATE]
    FROM @tbl
    ) AS tbl2
WHERE
    [STATUS] = 'ACTIVE'
    AND [STATUSDATE] = '05-04-2013'
    AND [previous_status] = 'INACTIVE'
    AND [previous_status_date] = '06-30-2007'