SQL Server 2008 R2:将列拆分为两个

时间:2017-10-05 10:24:10

标签: sql sql-server sql-server-2008-r2

我有以下名为tbl_Rightstbl_Rights_history的表,其中包含 有关员工权利和修改历史的信息。

表格结构:

CREATE TABLE Tbl_Rights
(
    Rights_ID int,
    Rights_name varchar(10)
);

CREATE TABLE Tbl_Rights_history
(
    EMPID int,
    EMPName varchar(50),
    Rights_ID int,
    ModifiedDate datetime
);

插入数据:

INSERT INTO Tbl_Rights VALUES(1,'Guest')
INSERT INTO Tbl_Rights VALUES(2,'Admin')

INSERT INTO Tbl_Rights_history VALUES(1,'Sam',1,'2010-01-01 10:12:02.563')
INSERT INTO Tbl_Rights_history VALUES(1,'Sam',2,'2010-01-02 11:32:10.125')
INSERT INTO Tbl_Rights_history VALUES(1,'Sam',1,'2010-01-03 12:22:11.478')
INSERT INTO Tbl_Rights_history VALUES(2,'Mak',1,'2010-02-01 11:44:16.196')
INSERT INTO Tbl_Rights_history VALUES(2,'Mak',2,'2010-03-02 12:37:26.568')

预期产出:

EMPName Old_Rights  New_Rights  ModifiedDate_1              ModifiedDate_2
----------------------------------------------------------------------------------
Sam     Guest       Admin       2010-01-01 10:12:02.563     2010-01-02 11:32:10.127
Sam     Admin       Guest       2010-01-02 11:32:10.127     2010-01-03 12:22:11.477
Mak     Guest       Admin       2010-02-01 11:44:16.197     2010-03-02 12:37:26.567

我的尝试:

;WITH CTE1 AS
(
    SELECT  t1.EMPID,
            t1.EMPName,
            t2.Rights_name,
            t1.ModifiedDate,
            DENSE_RANK() OVER(PARTITION BY t1.EMPID ORDER BY t1.ModifiedDate ASC) rn
    FROM Tbl_Rights_history t1
    LEFT JOIN Tbl_Rights t2
        ON t1.Rights_ID = t2.Rights_ID
)
SELECT  c.EMPName,
        CASE WHEN rn = 1 THEN c.Rights_Name END Old_Rights,
        CASE WHEN rn > 1 THEN c.Rights_Name END New_Rigths,
        CASE WHEN rn = 1 THEN c.ModifiedDate END ModifiedDate_1,
        CASE WHEN rn > 1 THEN c.ModifiedDate END ModifiedDate_2 
FROM CTE1 c;

但获得意外的输出:

EMPName Old_Rights  New_Rigths  ModifiedDate_1          ModifiedDate_2
-------------------------------------------------------------------------------
Sam     Guest       NULL        2010-01-01 10:12:02.563 NULL
Sam     NULL        Admin       NULL                    2010-01-02 11:32:10.127
Sam     NULL        Guest       NULL                    2010-01-03 12:22:11.477
Mak     Guest       NULL        2010-02-01 11:44:16.197 NULL
Mak     NULL        Admin       NULL                    2010-03-02 12:37:26.567     

2 个答案:

答案 0 :(得分:2)

你可以试试这个

;WITH T AS (
    SELECT t1.*, 
        t2.Rights_name, 
        RN=ROW_NUMBER() OVER(PARTITION BY EMPID ORDER BY ModifiedDate ASC )  
    FROM Tbl_Rights_history t1
        LEFT JOIN Tbl_Rights t2 ON t1.Rights_ID = t2.Rights_ID
)
SELECT 
    T1.EMPName, 
    T2.Rights_name Old_Rights, 
    T1.Rights_name New_Rights, 
    T2.ModifiedDate ModifiedDate_1, 
    T1.ModifiedDate ModifiedDate_2
FROM T T1
    INNER JOIN T T2 ON T1.RN = T2.RN +1 AND T1.EMPID = T2.EMPID

结果:

EMPName     Old_Rights New_Rights ModifiedDate_1          ModifiedDate_2
----------- ---------- ---------- ----------------------- -----------------------
Sam         Guest      Admin      2010-01-01 10:12:02.563 2010-01-02 11:32:10.127
Sam         Admin      Guest      2010-01-02 11:32:10.127 2010-01-03 12:22:11.477
Mak         Guest      Admin      2010-02-01 11:44:16.197 2010-03-02 12:37:26.567

答案 1 :(得分:0)

declare @Tbl_Rights table(
Rights_ID   int
 , Rights_Name nvarchar(10)
);
declare @Tbl_Rights table(
   Rights_ID   int
 , Rights_Name nvarchar(10)
);

declare @Tbl_Rights_history table(
   EMPID        int
 , EMPName      nvarchar(50)
 , Rights_ID    int
 , ModifiedDate datetime
);

insert @Tbl_Rights
values (1, N'Guest')
     , (2, N'Admin')
     , (3, N'User' )

insert @Tbl_Rights_history
values (1, N'Sam', 1, '2010-01-01T10:12:02.563')
     , (1, N'Sam', 2, '2010-01-02T11:32:10.125')
     , (1, N'Sam', 1, '2010-01-03T12:22:11.478')
     , (2, N'Mak', 1, '2010-02-01T11:44:16.196')
     , (2, N'Mak', 2, '2010-03-02T12:37:26.568')
     , (3, N'Nik', 3, '2010-03-02T12:37:26.568')

;with cte as(
select
   trh.*
 , row_Number() over (partition by trh.EMPID order by trh.ModifiedDate desc) as RN
 , tr.Rights_Name
from @Tbl_Rights_history trh
     join @Tbl_Rights tr on tr.Rights_ID = trh.Rights_ID
)
select
   new.EMPName
 , old.Rights_Name  as RightsOld
 , new.Rights_Name  as RightsNew
 , old.ModifiedDate as ModifiedDateOld
 , new.ModifiedDate as ModifiedDateNew
from cte new
     left join cte old on old.EMPID = new.EMPID and old.RN = 2
where new.RN = 1

结果:

EMPName RightsOld  RightsNew  ModifiedDateOld   ModifiedDateNew
------- ---------- ---------- ----------------- -------------------
Sam     Admin      Guest      2010-01-02 11:32  2010-01-03 12:22:11
Mak     Guest      Admin      2010-02-01 11:44  2010-03-02 12:37:26
Nik     NULL       User       NULL              2010-03-02 12:37:26
(3 row(s) affected)