Select 行具有基于值更改的最近两个日期

Select rows with the most recent two dates based on value changes

我有一个table

日期 Job_Id Employee_ID 状态
2021-01-01 老师 10 有效
2021-02-01 老师 10 有效
2021-03-01 老师 10 退休
2021-04-01 老师 10 有效
2021-01-01 理发师 11 有效
2021-02-01 理发师 11 已暂停
2021-03-01 理发师 11 有效
2021-04-01 理发师 11 有效

我想查询 return 这个结果集

日期 Job_Id Employee_ID 状态
2021-03-01 老师 10 退休
2021-04-01 老师 10 有效
2021-02-01 理发师 11 已暂停
2021-03-01 理发师 11 有效

本质上应该是return状态变化时最近的两条记录。 我目前正在试验滞后函数,但我还不太精通 SQL,这就是我遇到的问题。

SELECT Date, Job_ID,Employee_ID, [Status], PrevStatus FROM 
    (
    SELECT 
Date,
    Job_ID,
      Employee_ID,
      [Status],
      LAG([Status]) OVER (PARTITION BY Job_ID ORDER BY ExtractDate ) AS PrevStatus
FROM    #Statuses
) AS a
WHERE a.PrevStatus <> [Status] AND a.PrevStatus IS NOT NULL

有人对如何修改这个有什么想法吗?

嗯,我猜你需要 lag() and lead() 来获取下一个 or[= 状态的所有行21=] 上一行发生变化。然后,您需要对该结果使用 row_number() 以获得最后两个结果。

SELECT date,
       job_id,
       employee_id,
       status
       FROM (SELECT date,
                    job_id,
                    employee_id,
                    status,
                    row_number() OVER (PARTITION BY employee_id,
                                                    job_id
                                       ORDER BY date DESC) row_number
                    FROM (SELECT date,
                                 job_id,
                                 employee_id,
                                 status,
                                 lag(status, 1, status) OVER (PARTITION BY employee_id,
                                                                           job_id
                                                              ORDER BY date ASC) prevstatus,
                                 lead(status, 1, status) OVER (PARTITION BY employee_id,
                                                                            job_id
                                                               ORDER BY date ASC) nextstatus
                                 FROM elbat) x
                    WHERE status <> prevstatus
                           OR status <> nextstatus) y
            WHERE row_number <= 2
            ORDER BY employee_id ASC,
                     date ASC;

db<>fiddle

您想要的似乎与每个员工的最后 2 个唯一状态相同

SELECT *
FROM
(
    select *, 
           rn = row_number() over (partition by Employee_ID, [Status]
                                       order by [Date] desc)
    from   #Statuses
) d
WHERE  d.rn = 1
order by Employee_ID, [Date]

也许,我不明白用例,但你为什么要使用 LAG?

我会做这样的事情吗?

SELECT MAX(Date), Job_Id, Employee_ID, Status
FROM #Statuses
GROUP BY Job_ID, Employee_ID, Status