动态旋转到固定数量的列
Dynamically pivot to fixed number of columns
这是我的数据结构
Name TransID Amount
Joe 123 56
Joe 124 55
Joe 125 58
Tom 126 31
Tom 127 48
我需要按以下格式报告此数据
Name Amount1 Amount2
Joe 56 55
Joe 58
Tom 31 48
Joe 在原始数据集中有三个 Amounts,但我需要在视图中有固定数量的列(两列)。因此,Joe 的第三个 Amount 作为新记录插入到视图中。是否可以通过存储过程或创建视图来实现。
将问题分解成更小的步骤。这些是我将采取的步骤:
使用ROW_NUMBER() OVER (PARTITION BY ...):
Name TransID Amount Row_Number
Joe 123 56 1
Joe 124 55 2
Joe 125 58 3
Tom 126 31 1
Tom 127 48 2
减 1。
Name TransID Amount RowNumberStartingWith0
Joe 123 56 0
Joe 124 55 1
Joe 125 58 2
Tom 126 31 0
Tom 127 48 1
除以2,取余数对2取模:
Name TransID Amount Result Remainder
Joe 123 56 0 0
Joe 124 55 0 1
Joe 125 58 1 0
Tom 126 31 0 0
Tom 127 48 0 1
删除 TransID
列。余数始终为 0 或 1,因此您可以以此为中心:
Name Result AmountForRemainder0 AmountForRemainder1
Joe 0 56 55
Joe 1 58
Tom 0 31 48
现在您删除 Result
列并重命名您的列:
Name Amount1 Amount2
Joe 56 55
Joe 58
Tom 31 48
利润。
试试这个,让我知道。检查其他样本数据also.I我得到了想要的输出。
DECLARE @t TABLE (
NAME VARCHAR(50)
,TransID INT
,Amount INT
)
INSERT INTO @t
VALUES ('Joe',123,56)
,('Joe',124,55)
,('Joe',125,58)
,('Tom',126,31)
,('Tom',127,48)
,('Tom',128,89)
,('Tom',129,90)
,('Joe',130,68);
WITH CTE
AS (
SELECT *
,row_number() OVER (
PARTITION BY NAME ORDER BY amount
) rn
FROM @t
)
,CTE1
AS (
SELECT NAME
,(
SELECT amount
FROM cte
WHERE rn = 1
AND NAME = a.NAME
) [Amount1]
,(
SELECT amount
FROM cte
WHERE rn = 2
AND NAME = a.NAME
) [Amount2]
,rn
FROM cte A
WHERE rn = 1
UNION ALL
SELECT b.NAME
,a.amount
,isnull(c.amount, 0)
,a.rn
FROM CTE1 B
INNER JOIN CTE A ON a.NAME = b.NAME
AND a.rn % 2 <> 0
AND a.rn > 1
AND b.rn <> a.rn
OUTER APPLY (
SELECT Amount
FROM CTE C
WHERE NAME = b.NAME
AND rn % 2 = 0
AND rn > 2
) c
)
SELECT *
FROM cte1
这是我的数据结构
Name TransID Amount
Joe 123 56
Joe 124 55
Joe 125 58
Tom 126 31
Tom 127 48
我需要按以下格式报告此数据
Name Amount1 Amount2
Joe 56 55
Joe 58
Tom 31 48
Joe 在原始数据集中有三个 Amounts,但我需要在视图中有固定数量的列(两列)。因此,Joe 的第三个 Amount 作为新记录插入到视图中。是否可以通过存储过程或创建视图来实现。
将问题分解成更小的步骤。这些是我将采取的步骤:
使用ROW_NUMBER() OVER (PARTITION BY ...):
Name TransID Amount Row_Number Joe 123 56 1 Joe 124 55 2 Joe 125 58 3 Tom 126 31 1 Tom 127 48 2
减 1。
Name TransID Amount RowNumberStartingWith0 Joe 123 56 0 Joe 124 55 1 Joe 125 58 2 Tom 126 31 0 Tom 127 48 1
除以2,取余数对2取模:
Name TransID Amount Result Remainder Joe 123 56 0 0 Joe 124 55 0 1 Joe 125 58 1 0 Tom 126 31 0 0 Tom 127 48 0 1
删除
TransID
列。余数始终为 0 或 1,因此您可以以此为中心:Name Result AmountForRemainder0 AmountForRemainder1 Joe 0 56 55 Joe 1 58 Tom 0 31 48
现在您删除
Result
列并重命名您的列:Name Amount1 Amount2 Joe 56 55 Joe 58 Tom 31 48
利润。
试试这个,让我知道。检查其他样本数据also.I我得到了想要的输出。
DECLARE @t TABLE (
NAME VARCHAR(50)
,TransID INT
,Amount INT
)
INSERT INTO @t
VALUES ('Joe',123,56)
,('Joe',124,55)
,('Joe',125,58)
,('Tom',126,31)
,('Tom',127,48)
,('Tom',128,89)
,('Tom',129,90)
,('Joe',130,68);
WITH CTE
AS (
SELECT *
,row_number() OVER (
PARTITION BY NAME ORDER BY amount
) rn
FROM @t
)
,CTE1
AS (
SELECT NAME
,(
SELECT amount
FROM cte
WHERE rn = 1
AND NAME = a.NAME
) [Amount1]
,(
SELECT amount
FROM cte
WHERE rn = 2
AND NAME = a.NAME
) [Amount2]
,rn
FROM cte A
WHERE rn = 1
UNION ALL
SELECT b.NAME
,a.amount
,isnull(c.amount, 0)
,a.rn
FROM CTE1 B
INNER JOIN CTE A ON a.NAME = b.NAME
AND a.rn % 2 <> 0
AND a.rn > 1
AND b.rn <> a.rn
OUTER APPLY (
SELECT Amount
FROM CTE C
WHERE NAME = b.NAME
AND rn % 2 = 0
AND rn > 2
) c
)
SELECT *
FROM cte1