sql - SQL - 查找快照日期之间的新开始者和离开者的数量
问题描述
我有一个 SQL 表staff
,它在特定日期拍摄快照并添加每一行staffID
和相应的DateID
.
我需要找出自下一次以来有多少员工加入DateID
,以及离开了多少。
因此,在staff
下面 DateID B 的示例表中,StaffID
's002
和003
fromDateID
A
不存在,所以有 'left',并且DateID
B
有staffID
's 004
, 005
,006
它们不存在,DateID
所以是 'new'。
StaffID DateID
007 C
005 C
006 B
005 B
004 B
001 B
003 A
002 A
001 A
我推测这些结果将如何出现在下面。
DateID New Leavers
A 0 2
B 3 2
C 1 3
我目前也是唯一解决这个问题的方法是通过之前DateID
的每一个,DateID
然后加入较旧的日期,计算旧日期为空的行以获取新员工的数量,并为离开者交换表格。
SELECT t1.DateID, count(*) AS Total
(SELECT *
FROM staff
WHERE DateID = 'B') t1
LEFT JOIN
(SELECT *
FROM staff
WHERE DateID = 'A') t2
ON t1.StaffID = t2.StaffID
WHERE t2.StaffID is null
GROUP BY t1.DateID
这种方法对于一个更大的表来说效率非常低,希望任何人都可以在一个脚本中找到一种方法。或者,只为新员工准备的脚本和只为离职人员准备的脚本也一样好。
按照@Larnu 的要求,我添加了一个snapshot
包含所有DateID 的表。该staff
表被过滤为仅显示每周的 DateID。
DateID Weekly Monthly Yearly
A Y Y N
B Y N N
C Y N N
D N N N
E Y Y N
F N N Y
解决方案
LEAD
和LAG
窗口功能在这里会有所帮助。
由于DateID
s 不是连续的,因此您还需要计算LEAD/LAG
它,然后加入它
SELECT
s.DateID,
[New] = COUNT(CASE WHEN s.PrevID IS NULL OR s.PrevID <> d.PrevDateID THEN 1 END),
Leavers = COUNT(CASE WHEN s.NextID IS NULL OR s.NextID <> d.NextDateID THEN 1 END)
FROM (
SELECT *,
PrevDateID = LAG(DateID) OVER (ORDER BY DateID),
NextDateID = LEAD(DateID) OVER (ORDER BY DateID)
FROM Dates d
) d
JOIN (
SELECT *,
PrevID = LAG(s.DateID) OVER (PARTITION BY StaffID ORDER BY DateID),
NextID = LEAD(s.DateID) OVER (PARTITION BY StaffID ORDER BY DateID)
FROM staff s
) s ON s.DateID = d.DateID
GROUP BY
s.DateID;
推荐阅读
- python - 根据另一列覆盖数据框中的数据
- c - 为什么将编译时静态字符串作为参数传递给字符串格式化函数,而不是将其包含在格式字符串中?
- r - 有没有办法“合并”两列,其中新列的值是具有特定值的原始列的名称,分组明智?
- javascript - 数据表显示条目和搜索功能不起作用
- c# - 具有无法正确关闭 SQL 连接的 ac# 代码(可能)
- css - 当我切换类时,我需要什么代码才能显示正面类?
- r - 使用 mutate 和 case_when 的用户定义函数
- java - 将字符串从活动传递到片段
- arrays - 在 Rust 中,我可以在不硬编码值的情况下实例化我的 const 数组吗?编译时评估?
- quantlib - 使用哪种利率来计算 IV:FlatForward 没有意义?