这是源表emp, 查看下表中的表格和所需输出:
EMP: 这里是来源表:
EMPID ENAME STANDING DATE
101 ABC ACTIVE 10-06-91
101 ABC INACTIVE 01-07-2002
102 EFG INACTIVE 02-09-2009
102 EFG ACTIVE 01-10-2011
102 EFG INACTIVE 07-10-2017
103 XYZ ACTIVE 08-07-2010
103 XYZ ACTIVE 08-07-2010
103 XYZ INACTIVE 09-10-2011
输出:
EMPID ENAME BEFORESTANDING CURRENTSTANDING DATE
101 ABC ACTVE INACTIVE 01-07-2002
102 EFG INACTIVE ACTIVE 01-10-2011
102 EFG ACTIVE INACTIVE 07-10-2017
103 XYZ ACTIVE INACTIVE 09-10-2011
转换规则逻辑是指如果empid是相同的并且它已将STANDING从活动更改为非活动状态, 输出将在一行中,日期库存将来自最新记录。
如果表有三个非活动状态到活动状态并且活动状态为非活动状态,我们将在输出中保留2行[(n-1)用于输出] 随着积分的变化
如果表格在连续的行中有相同的排名,那么将跳过第一个,只考虑排名的变化。
答案 0 :(得分:1)
如果您使用的是SQL Server 2012或更高版本,则可以使用LAG()函数
轻松完成此操作WITH CTE_Source AS
(
SELECT *
, LAG(STANDING) OVER (PARTITION BY EmpID, Ename ORDER BY DATE) AS BEFORE_STANDING
FROM Emp
)
SELECT *
FROM CTE_Source
WHERE BEFORE_STANDING <> STANDING
答案 1 :(得分:0)
假设您使用的是SQL Server 2012或更高版本,以下应该可以解决问题...
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
CREATE TABLE #TestData (
EMPID INT NOT NULL,
ENAME CHAR(3) NOT NULL,
STANDING VARCHAR(10) NOT NULL,
[DATE] DATE NOT NULL
);
INSERT #TestData (EMPID, ENAME, STANDING, [DATE]) VALUES
('101', 'ABC', 'ACTIVE ', '10-06-1991'),
('101', 'ABC', 'INACTIVE', '01-07-2002'),
('102', 'EFG', 'INACTIVE', '02-09-2009'),
('102', 'EFG', 'ACTIVE ', '01-10-2011'),
('102', 'EFG', 'INACTIVE', '07-10-2017'),
('103', 'XYZ', 'ACTIVE ', '08-07-2010'),
('103', 'XYZ', 'ACTIVE ', '08-07-2010'),
('103', 'XYZ', 'INACTIVE', '09-10-2011');
--=============================================
WITH
cte_AddBeforeStanding AS (
SELECT
td.EMPID,
td.ENAME,
BEFORESTANDING = LAG(td.STANDING, 1) OVER (PARTITION BY td.EMPID ORDER BY td.DATE),
CURRENTSTANDING = td.STANDING,
td.DATE
FROM
#TestData td
)
SELECT
bs.EMPID,
bs.ENAME,
bs.BEFORESTANDING,
bs.CURRENTSTANDING,
bs.DATE
FROM
cte_AddBeforeStanding bs
WHERE
bs.BEFORESTANDING <> bs.CURRENTSTANDING;
HTH,Jason
答案 2 :(得分:0)
LAG
, SQL SERVER 2012+
是最好的方法,如果您使用的是旧版本,那么有一些方法可以做到这一点
Cross Apply
:
SELECT a.EMPID,
a.ENAME,
BEFORESTANDING= cs.STANDING,
CURRENTSTANDING= a.STANDING,
a.date
FROM Yourtable a
CROSS apply (SELECT TOP 1 *
FROM Yourtable b
WHERE a.EMPID = b.EMPID
AND a.DATE > b.DATE
ORDER BY b.Date DESC) AS cs
SELF JOIN
:
WITH CTE
AS (SELECT *,
Rn = Row_number()OVER(partition BY EMPID ORDER BY DATE)
FROM Yourtable)
SELECT a.EMPID,
a.ENAME,
BEFORESTANDING = b.STANDING,
CURRENTSTANDING= a.STANDING,
a.DATE
FROM CTE a
JOIN CTE b
ON a.EMPID = b.EMPID
AND a.Rn = b.Rn + 1
WHERE a.STANDING <> b.STANDING
ORDER BY a.EMPID,
a.DATE