gpt4 book ai didi

sql - 在 SQL Server 中将行数据转换为列

转载 作者:行者123 更新时间:2023-12-02 08:40:19 24 4
gpt4 key购买 nike

今天我的同事要求我将数据从垂直暂存表转换为水平表。我的意思是将行转换为列。我使用 PIVOT 并解决了它。但是遇到这样的情况,如果数据字段重复出现,我在移动数据时遇到麻烦。

这是我正在处理的测试数据:

CREATE TABLE STAGING 
(
ENTITYID INT,
PROPERTYNAME VARCHAR(25),
PROPERTYVALUE VARCHAR(25)
)

INSERT INTO STAGING VALUES (1, 'NAME', 'DONNA')
INSERT INTO STAGING VALUES (1, 'SPOUSE', 'HENRY')
INSERT INTO STAGING VALUES (1, 'CHILD', 'JACK')
INSERT INTO STAGING VALUES (2, 'CHILD', 'KAYALA')

我使用 PIVOT 将行数据显示为列:

SELECT * FROM 
(SELECT ENTITYID, PROPERTYNAME, PROPERTYVALUE FROM STAGING) AS T
PIVOT (MAX(PROPERTYVALUE) FOR PROPERTYNAME IN (NAME, SPOUSE, CHILD)) AS T2

输出是:

ENTITYID    NAME    SPOUSE  CHILD
1 DONNA HENRY JACK
2 NULL NULL KAYALA

但他想要这样的输出:

ENTITYID    NAME    SPOUSE  CHILD   CHILD
1 DONNA HENRY JACK KAYALA

底线是可以有多个 CHILD 属性进入暂存表。我们需要考虑这一点并将所有 CHILDREN 移动到列。

这可能吗?

最佳答案

您可以向属性名称添加一个行号,这将允许您执行您想要的操作:

SELECT * FROM
(
SELECT ENTITYID
, PROPERTYNAME = PROPERTYNAME + CAST(ROW_NUMBER() OVER(PARTITION BY ENTITYID, PROPERTYNAME ORDER BY PROPERTYVALUE) AS VARCHAR(5))
,PROPERTYVALUE
FROM #STAGING
) AS T
PIVOT (MAX(PROPERTYVALUE) FOR PROPERTYNAME IN (NAME1, SPOUSE1, CHILD1, CHILD2, CHILD3, CHILD4, CHILD5)) AS T2

我在这里假设 ENTITYID 将 child 与 parent 联系起来,即同一个人的所有 child 的 ENTITYID 都为 1,但您的示例显示 Kayala 为 2。

这是一个演示:SQL Fiddle

如果您只想要 CHILD 字段的数字,您可以这样写:

PROPERTYNAME = CASE WHEN PROPERTYNAME LIKE '%CHILD%' THEN PROPERTYNAME + CAST(ROW_NUMBER() OVER(PARTITION BY ENTITYID, PROPERTYNAME ORDER BY PROPERTYVALUE) AS VARCHAR(5))                                                   ELSE PROPERTYNAME END

然后从您的 IN() 语句中的其他字段中删除数字。

奖励问题 - 动态执行上述操作:我们不想假设人们只有一个配偶或 2.3 个 child ,所以我们动态地执行所有操作:

DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)

SELECT @cols = STUFF((SELECT ',' + PROPERTYNAME
FROM (SELECT DISTINCT PROPERTYNAME = PROPERTYNAME + CAST(ROW_NUMBER() OVER(PARTITION BY ENTITYID, PROPERTYNAME ORDER BY PROPERTYVALUE) AS VARCHAR(5))
FROM STAGING )sub
ORDER BY CASE WHEN PROPERTYNAME LIKE '%NAME%' THEN 1
WHEN PROPERTYNAME LIKE '%SPOUSE%' THEN 2
WHEN PROPERTYNAME LIKE '%CHILD%' THEN 3
ELSE 4
END
,RIGHT(PROPERTYNAME,1)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')


SET @query = 'SELECT * FROM
(
SELECT ENTITYID, PROPERTYNAME = PROPERTYNAME + CAST(ROW_NUMBER() OVER(PARTITION BY ENTITYID, PROPERTYNAME ORDER BY PROPERTYVALUE) AS VARCHAR(5)),PROPERTYVALUE
FROM STAGING
) AS T
PIVOT (MAX(PROPERTYVALUE) FOR PROPERTYNAME IN ('+@cols+')) AS T2

'
EXEC(@query)

注意:排序仅适用于配偶 1-9 和子女 1-9,您可以调整以适应,但无论如何都是任意的。

关于sql - 在 SQL Server 中将行数据转换为列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17076089/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com