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;
您想要的似乎与每个员工的最后 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
我有一个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;
您想要的似乎与每个员工的最后 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