使用 VARCHAR 列旋转 SQL 服务器 table 时出现语法错误
Syntax error in pivoting a SQL Server table using VARCHAR columns
我在 SQL 服务器中有一个 table(~50m 行)如下所示:
PId CustomColumnName CustomColumnValue
1 PropertyA 1
1 PropertyB B
1 PropertyC C
2 PropertyA 1.5
2 PropertyB BB
2 PropertyC CC
3 PropertyD D1
3 PropertyA 2.0
我想 PIVOT
table 看起来像这样:
PId PropertyA PropertyB PropertyC PropertyD
1 1 B C NULL
2 1.5 BB CC NULL
3 2.0 NULL NULL D1
我知道SQL服务器有PIVOT
功能,所以我写了这样的东西:
SELECT *
FROM
(
SELECT [PId], [CustomColumnName], [CustomColumnValue]
FROM [myTable]
) AS src
PIVOT
(
MAX([CustomColumnValue]) -- Not sure how to aggregate VARCHAR data here
FOR [CustomColumnName] IN ('PropertyA', 'PropertyB', 'PropertyC', 'PropertyD')
) AS pvt
但是我遇到了 Incorrect syntax near 'PropertyA'
错误。我不确定 SQL 服务器的 PIVOT
功能是否可以实现我正在尝试做的事情(因为我认为我无法聚合 [CustomColumnValue]
,这是VARCHAR
类型)。 如果在我的用例中使用 PIVOT
不可行,是否有有效的替代方法来实现我正在尝试做的事情?
提前感谢您的 suggestions/answers!
--去掉单引号你会得到想要的结果集
;With cte(PId, CustomColumnName,CustomColumnValue)
AS
(
SELECT 1,'PropertyA','1' Union all
SELECT 1,'PropertyB','B' Union all
SELECT 1,'PropertyC','C' Union all
SELECT 2,'PropertyA','1.5' Union all
SELECT 2,'PropertyB','BB' Union all
SELECT 2,'PropertyC','CC' Union all
SELECT 3,'PropertyD','D1' Union all
SELECT 3,'PropertyA','2.0'
)
SELECT *
FROM
(
SELECT [PId], [CustomColumnName], [CustomColumnValue]
FROM cte
) AS src
PIVOT
(
MAX([CustomColumnValue])
FOR [CustomColumnName] IN (PropertyA, PropertyB, PropertyC, PropertyD)
) AS pvt
您可以使用动态生成相同的结果集Pivot.it如下
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
Drop table #temp
;With cte(PId, CustomColumnName,CustomColumnValue)
AS
(
SELECT 1,'PropertyA','1' Union all
SELECT 1,'PropertyB','B' Union all
SELECT 1,'PropertyC','C' Union all
SELECT 2,'PropertyA','1.5' Union all
SELECT 2,'PropertyB','BB' Union all
SELECT 2,'PropertyC','CC' Union all
SELECT 3,'PropertyD','D1' Union all
SELECT 3,'PropertyA','2.0'
)
SELECT * INTO #temp FROM cte
Declare
@Sql nvarchar(max),
@dynamicCol nvarchar(max)
--Create columns Dynamically
SELECT @dynamicCol=STUFF((SELECT DISTINCT ', '+ QUOTENAME(CustomColumnName )
From #temp For XML PATH ('')),1,1,'')
--SELECT @dynamicCol
SET @Sql='
SELECT [PId] ,'+ @dynamicCol +' From
(
SELECT [PId], [CustomColumnName], [CustomColumnValue] From
#temp
)AS Src
PIVOT
(
MAX([CustomColumnValue]) For [CustomColumnName] IN ('+@dynamicCol+')
)
AS Pvt'
PRINT @Sql
EXEC(@Sql)
删除引号。
SELECT *
FROM
(
SELECT [PId], [CustomColumnName], [CustomColumnValue]
FROM [myTable]
) AS src
PIVOT
(MAX([CustomColumnValue])
FOR [CustomColumnName] IN ([PropertyA], [PropertyB], [PropertyC], [PropertyD])
) AS pvt
GO
PId | PropertyA | PropertyB | PropertyC | PropertyD
--: | :-------- | :-------- | :-------- | :--------
1 | 1 | B | C | null
2 | 1.5 | BB | CC | null
3 | 2.0 | null | null | D1
dbfiddle here
您需要使用列的引用名
SELECT *
FROM
(
SELECT [PId], [CustomColumnName], [CustomColumnValue]
FROM [myTable]
) AS src
PIVOT
(
MAX([CustomColumnValue]) -- Not sure how to aggregate VARCHAR data here
FOR [CustomColumnName] IN ([PropertyA], [PropertyB], [PropertyC], [PropertyD]) --provide in squarebrackets if generating dynamic then use quotename() function of sql server
) AS pvt
我在 SQL 服务器中有一个 table(~50m 行)如下所示:
PId CustomColumnName CustomColumnValue
1 PropertyA 1
1 PropertyB B
1 PropertyC C
2 PropertyA 1.5
2 PropertyB BB
2 PropertyC CC
3 PropertyD D1
3 PropertyA 2.0
我想 PIVOT
table 看起来像这样:
PId PropertyA PropertyB PropertyC PropertyD
1 1 B C NULL
2 1.5 BB CC NULL
3 2.0 NULL NULL D1
我知道SQL服务器有PIVOT
功能,所以我写了这样的东西:
SELECT *
FROM
(
SELECT [PId], [CustomColumnName], [CustomColumnValue]
FROM [myTable]
) AS src
PIVOT
(
MAX([CustomColumnValue]) -- Not sure how to aggregate VARCHAR data here
FOR [CustomColumnName] IN ('PropertyA', 'PropertyB', 'PropertyC', 'PropertyD')
) AS pvt
但是我遇到了 Incorrect syntax near 'PropertyA'
错误。我不确定 SQL 服务器的 PIVOT
功能是否可以实现我正在尝试做的事情(因为我认为我无法聚合 [CustomColumnValue]
,这是VARCHAR
类型)。 如果在我的用例中使用 PIVOT
不可行,是否有有效的替代方法来实现我正在尝试做的事情?
提前感谢您的 suggestions/answers!
--去掉单引号你会得到想要的结果集
;With cte(PId, CustomColumnName,CustomColumnValue)
AS
(
SELECT 1,'PropertyA','1' Union all
SELECT 1,'PropertyB','B' Union all
SELECT 1,'PropertyC','C' Union all
SELECT 2,'PropertyA','1.5' Union all
SELECT 2,'PropertyB','BB' Union all
SELECT 2,'PropertyC','CC' Union all
SELECT 3,'PropertyD','D1' Union all
SELECT 3,'PropertyA','2.0'
)
SELECT *
FROM
(
SELECT [PId], [CustomColumnName], [CustomColumnValue]
FROM cte
) AS src
PIVOT
(
MAX([CustomColumnValue])
FOR [CustomColumnName] IN (PropertyA, PropertyB, PropertyC, PropertyD)
) AS pvt
您可以使用动态生成相同的结果集Pivot.it如下
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
Drop table #temp
;With cte(PId, CustomColumnName,CustomColumnValue)
AS
(
SELECT 1,'PropertyA','1' Union all
SELECT 1,'PropertyB','B' Union all
SELECT 1,'PropertyC','C' Union all
SELECT 2,'PropertyA','1.5' Union all
SELECT 2,'PropertyB','BB' Union all
SELECT 2,'PropertyC','CC' Union all
SELECT 3,'PropertyD','D1' Union all
SELECT 3,'PropertyA','2.0'
)
SELECT * INTO #temp FROM cte
Declare
@Sql nvarchar(max),
@dynamicCol nvarchar(max)
--Create columns Dynamically
SELECT @dynamicCol=STUFF((SELECT DISTINCT ', '+ QUOTENAME(CustomColumnName )
From #temp For XML PATH ('')),1,1,'')
--SELECT @dynamicCol
SET @Sql='
SELECT [PId] ,'+ @dynamicCol +' From
(
SELECT [PId], [CustomColumnName], [CustomColumnValue] From
#temp
)AS Src
PIVOT
(
MAX([CustomColumnValue]) For [CustomColumnName] IN ('+@dynamicCol+')
)
AS Pvt'
PRINT @Sql
EXEC(@Sql)
删除引号。
SELECT * FROM ( SELECT [PId], [CustomColumnName], [CustomColumnValue] FROM [myTable] ) AS src PIVOT (MAX([CustomColumnValue]) FOR [CustomColumnName] IN ([PropertyA], [PropertyB], [PropertyC], [PropertyD]) ) AS pvt GO
PId | PropertyA | PropertyB | PropertyC | PropertyD --: | :-------- | :-------- | :-------- | :-------- 1 | 1 | B | C | null 2 | 1.5 | BB | CC | null 3 | 2.0 | null | null | D1
dbfiddle here
您需要使用列的引用名
SELECT *
FROM
(
SELECT [PId], [CustomColumnName], [CustomColumnValue]
FROM [myTable]
) AS src
PIVOT
(
MAX([CustomColumnValue]) -- Not sure how to aggregate VARCHAR data here
FOR [CustomColumnName] IN ([PropertyA], [PropertyB], [PropertyC], [PropertyD]) --provide in squarebrackets if generating dynamic then use quotename() function of sql server
) AS pvt