如何获取员工当前任职部门起始日期、倒数第三个部门记录及验证分区可视化逻辑正确性
解决方案与问题解答
问题1:获取倒数第三个部门的起始日期记录
首先,你的现有SQL已经成功用SUM(counter)生成了按部门切换分组的grp列,接下来要拿到每个员工倒数第三个部门的记录,咱们可以分两步走:先给每个员工的部门组(grp)按时间倒序排名,再筛选出排名为3的组,最后取该组的第一条记录(也就是部门的起始日期)。
修正并扩展你的SQL如下:
WITH dept_groups AS ( -- 修正原SQL的语法细节(别名、括号、分区字段) SELECT loginName, emp_name, dept_id, dept_name, startDate, endDate, SUM(counter) OVER (PARTITION BY emp_name ORDER BY startDate) AS grp FROM ( SELECT loginName, emp_name, dept_id, dept_name, startDate, endDate, -- 调整分区逻辑:只按员工分组,部门变化时counter置1 CASE WHEN dept_name = LAG(dept_name) OVER (PARTITION BY loginName, emp_name ORDER BY startDate) THEN 0 ELSE 1 END AS counter FROM empdepthist ) AS sub_query ), grp_rankings AS ( -- 给每个员工的部门组按倒序排名(最大的grp是最新部门,排名1) SELECT loginName, emp_name, grp, DENSE_RANK() OVER (PARTITION BY emp_name ORDER BY grp DESC) AS grp_rank FROM dept_groups GROUP BY loginName, emp_name, grp -- 去重每个员工的唯一部门组 ) -- 筛选倒数第三个部门组,取该组的第一条记录(部门起始日期) SELECT dg.loginName, dg.emp_name, dg.dept_id, dg.dept_name, dg.startDate, dg.endDate FROM dept_groups dg JOIN grp_rankings gr ON dg.loginName = gr.loginName AND dg.emp_name = gr.emp_name AND dg.grp = gr.grp WHERE gr.grp_rank = 3 QUALIFY ROW_NUMBER() OVER (PARTITION BY dg.loginName, dg.emp_name ORDER BY dg.startDate) = 1;
关键逻辑说明:
dept_groups:修正了原SQL的分区逻辑(原PARTITION BY login_name, emp_name, dept_id会导致部门内重复记录的LAG无效,改为按员工分组即可),生成正确的部门组grp。grp_rankings:用DENSE_RANK()给每个员工的部门组从新到旧排名,排名3的就是倒数第三个部门。- 最后用
QUALIFY筛选出该部门组的第一条记录,也就是你要的部门起始日期,和预期输出完全匹配。
问题2:数据可视化格式验证与Pattern/Measures适用性
格式正确性
你更新的可视化格式是正确的:
PartitionByEMpName列:因为当前数据集只有1名员工,PARTITION BY loginName后所有行都属于同一个分区,所以值为1是合理的;如果有多名员工,该列会按员工区分不同的分区值。GroupInPartiton列:用DEFINE same_dept AS FIRST(dept_id) = dept_id定义分组,同一部门的所有行都会因为FIRST(dept_id)等于当前行的dept_id而分到同一个组(a/b/c/d),完美区分了不同的部门阶段,可视化逻辑准确。
Pattern与Measures的适用性
完全可以基于这个格式使用Pattern和Measures处理数据!尤其在支持MATCH_RECOGNIZE的数据库(比如Oracle、Snowflake等)中,这种分组后的结构非常适合识别部门切换的序列模式。
举个例子,直接用MATCH_RECOGNIZE获取倒数第三个部门的起始记录,不需要提前计算grp:
SELECT loginName, emp_name, dept_id, dept_name, startDate, endDate FROM empdepthist MATCH_RECOGNIZE ( PARTITION BY loginName, emp_name ORDER BY startDate MEASURES prev_prev_dept.dept_id AS dept_id, prev_prev_dept.dept_name AS dept_name, prev_prev_dept.startDate AS startDate, prev_prev_dept.endDate AS endDate PATTERN ( .* prev_prev_dept prev_dept current_dept ) DEFINE prev_dept AS dept_id != LAG(dept_id), -- 倒数第二个部门的起始行 current_dept AS dept_id != LAG(dept_id) OR endDate IS NULL, -- 当前部门的起始行 prev_prev_dept AS dept_id != LAG(dept_id) -- 倒数第三个部门的起始行 );
这种方式直接通过模式匹配识别部门切换的序列,更直观地定位到你需要的倒数第三个部门记录。
内容的提问来源于stack exchange,提问作者FreshTransistor
相关产品推荐
相关产品推荐

