我是SQL的新手(更确切地说是T-SQL),我似乎无法绕过这个。我确定有一个简单的解决方案,我只是没想到(可能涉及子查询和/或表格枢轴)。但我希望你们中的一个SQL高手可以帮助一个无能的新手。
基本上,我需要转换这些数据:
CaseNumber|DecisionNumber|Date |Decision
----------+--------------+-----------+--------
444 |29833 |04/05/2005 |Sell
444 |29777 |05/10/2006 |Sell
444 |29654 |08/19/2007 |Buy
468 |29230 |08/19/2006 |Sell
468 |29192 |08/19/2011 |Sell
进入这个结果:
CaseNumber|DecisionNumber1|Date1 |Decision1|DecisionNumber2|Date2 |Decision2|DecisionNumber3|Date3 |Decision3
----------+---------------+------------+---------+---------------+------------+---------+---------------+------------+---------
444 |29833 |04/05/2005 |Sell |29777 |05/10/2006 |Sell |29654 |08/19/2007 |Buy
468 |29230 |08/19/2006 |Sell |29192 |08/19/2011 |Sell |NULL |NULL |NULL
任何想法都会受到青睐。
答案 0 :(得分:1)
您尝试执行的操作的问题在于您尝试一次调整多个列。这可以使用unpivot
然后pivot
来完成。像这样:
WITH CTE
AS
(
SELECT
CAST(CaseNumber AS NVARCHAR(50)) AS CaseNumber
,CAST(DecisionNumber AS NVARCHAR(50)) AS DecisionNumber
,CAST(Date AS NVARCHAR(50)) AS [Date]
,ROW_NUMBER() OVER(PARTITION BY [CaseNumber] ORDER BY DecisionNumber DESC) AS RN
FROM Table1
), unpivoted
AS
(
SELECT CaseNumber, val, col + ' ' + CAST(RN AS NVARCHAR(50)) AS col
FROM CTE
UNPIVOT
(
val
FOR col IN(DecisionNumber, Date)
) AS u
)
SELECT *
FROM unpivoted AS u
PIVOT
(
MAX(val)
FOR col IN([DecisionNumber 1], [Date 1],
[DecisionNumber 2], [Date 2],
[DecisionNumber 3], [Date 3])
) AS p;
这会给你:
| CaseNumber | DecisionNumber 1 | Date 1 | DecisionNumber 2 | Date 2 | DecisionNumber 3 | Date 3 |
|------------|------------------|------------|------------------|------------|------------------|------------|
| 444 | 29833 | 2005-04-05 | 29777 | 2006-05-10 | 29654 | 2007-08-19 |
| 468 | 29230 | 2006-08-19 | 29192 | 2011-08-19 | (null) | (null) |
但是,如果您要对任意数量的decisionnumber
和date
执行此操作,则可以执行以下操作:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
WITH CTE
AS
(
SELECT
CAST(CaseNumber AS NVARCHAR(50)) AS CaseNumber
,CAST(DecisionNumber AS NVARCHAR(50)) AS DecisionNumber
,CAST(Date AS NVARCHAR(50)) AS [Date]
,ROW_NUMBER() OVER(PARTITION BY [CaseNumber] ORDER BY DecisionNumber DESC) AS RN
FROM Table1
), Data
AS
(
SELECT col, MAX(RN) AS RN
FROM
(
SELECT RN, col + CAST(RN AS NVARCHAR(50)) AS col
FROM CTE
UNPIVOT
(
val
FOR col IN(DecisionNumber, Date)
) AS u
) AS t
GROUP BY col
)
select @cols = STUFF((SELECT ',' +
QUOTENAME(col)
FROM Data
ORDER BY RN
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SELECT @query = 'WITH CTE
AS
(
SELECT
CAST(CaseNumber AS NVARCHAR(50)) AS CaseNumber
,CAST(DecisionNumber AS NVARCHAR(50)) AS DecisionNumber
,CAST(Date AS NVARCHAR(50)) AS [Date]
,ROW_NUMBER() OVER(PARTITION BY [CaseNumber] ORDER BY DecisionNumber DESC) AS RN
FROM Table1
), unpivoted
AS
(
SELECT CaseNumber, val, col + CAST(RN AS NVARCHAR(50)) AS col
FROM CTE
UNPIVOT
(
val
FOR col IN(DecisionNumber, Date)
) AS u
)
SELECT *
FROM unpivoted AS u
PIVOT
(
MAX(val)
FOR col IN('+ @cols + ')
) AS p;';
EXECUTE(@query);