如果有一个包含员工状态和生效日期的表格,我如何只检索反映状态变化的数据?
例如,给定以下结构:
DECLARE @STATUSES TABLE(
EMPLOYEE_ID INT NOT NULL,
EFFECTIVE_DATE DATE NOT NULL,
STATUS_CODE CHAR(1) NOT NULL
)
INSERT @STATUSES VALUES (1, '2012-01-01', 'A')
INSERT @STATUSES VALUES (1, '2012-02-28', 'A')
INSERT @STATUSES VALUES (1, '2012-03-01', 'T')
INSERT @STATUSES VALUES (2, '2012-01-01', 'A')
INSERT @STATUSES VALUES (2, '2012-02-14', 'A')
INSERT @STATUSES VALUES (2, '2012-03-10', 'A')
INSERT @STATUSES VALUES (3, '2012-02-01', 'A')
INSERT @STATUSES VALUES (3, '2012-03-17', 'A')
INSERT @STATUSES VALUES (3, '2012-03-18', 'T')
INSERT @STATUSES VALUES (3, '2012-04-01', 'A')
INSERT @STATUSES VALUES (4, '2012-03-01', 'A')
可以使用什么查询来产生以下内容?
EMPLOYEE_ID EFFECTIVE_DATE STATUS_CODE
1 2012-01-01 A
1 2012-03-01 T
2 2012-01-01 A
3 2012-02-01 A
3 2012-03-18 T
3 2012-04-01 A
4 2012-03-01 A
换句话说,如果存在具有较早生效日期的记录,我想省略那些具有与之前相同的员工ID和状态代码的记录。请注意,员工1仅列出两次,因为状态只有两个实际变化 - 2012-02-28中的变更无关紧要,因为状态从较早的日期没有变化。另请注意,员工2只列出一次,因为他的状态从未改变,尽管有三条记录。每次更改只显示最早的日期。
答案 0 :(得分:1)
通过一些进一步的实验,看起来这将做我想要的。
;WITH cte
AS (SELECT ROW_NUMBER() OVER (PARTITION BY EMPLOYEE_ID ORDER BY EFFECTIVE_DATE) AS rownum
,EMPLOYEE_ID
,EFFECTIVE_DATE
,STATUS_CODE
FROM @STATUSES)
SELECT t2.EMPLOYEE_ID
,t2.EFFECTIVE_DATE
,t2.STATUS_CODE
FROM cte t2
LEFT JOIN cte t1
ON t2.EMPLOYEE_ID = t1.EMPLOYEE_ID
AND t2.STATUS_CODE = t1.STATUS_CODE
AND t2.rownum = t1.rownum + 1
WHERE t1.EMPLOYEE_ID IS NULL
答案 1 :(得分:0)
SELECT
EMPLOYEE_ID, MIN(EFFECTIVE_DATE) AS EFFECTIVE_DATE, STATUS_CODE
FROM
(
SELECT
T1.EMPLOYEE_ID, T1.EFFECTIVE_DATE, T1.STATUS_CODE,
MAX(T2.EFFECTIVE_DATE) AS MOST_RECENT_PREVIOUS_STATUS_DATE
FROM
@STATUSES T1
LEFT JOIN
@STATUSES T2
ON
T1.EMPLOYEE_ID = T2.EMPLOYEE_ID
AND
T1.EFFECTIVE_DATE > T2.EFFECTIVE_DATE
AND
T1.STATUS_CODE <> T2.STATUS_CODE
GROUP BY
T1.EMPLOYEE_ID, T1.EFFECTIVE_DATE, T1.STATUS_CODE
) SubQuery
GROUP BY
EMPLOYEE_ID, STATUS_CODE, MOST_RECENT_PREVIOUS_STATUS_DATE
答案 2 :(得分:0)
您可以使用游标
您需要两组变量:@PreviousRecord和@CurrentRecord
声明按employeeid和date
排序的表的游标将光标中的第一条记录提取到@PreviousRecord变量中 - 根据您的要求将此注册为重要更改(将记录写入临时表)
然后设置一个循环:
获取@CurrentRecord变量的下一条记录
将其与之前的记录进行比较,如果符合您对重大变更的要求,请将其写入临时表
将@CurrentRecord值移动到@PreviousRecord变量
我有兴趣知道CTE方法是否更有效