【问题标题】:Syntax error in pivoting a SQL Server table using VARCHAR columns使用 VARCHAR 列对 SQL Server 表进行透视时出现语法错误
【发布时间】:2017-05-18 14:33:30
【问题描述】:

我在 SQL Server 中有一个如下表(约 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 那张桌子看起来像这样:

PId    PropertyA    PropertyB    PropertyC    PropertyD
1      1            B            C            NULL
2      1.5          BB           CC           NULL
3      2.0          NULL         NULL         D1

我知道 SQL Server 有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 Server 的PIVOT 函数(因为我认为我不能聚合[CustomColumnValue],它是VARCHAR 类型)。 如果在我的用例中使用 PIVOT 不可行,是否有一种有效的替代方法来实现我想要做的事情?

非常感谢您的建议/回答!

【问题讨论】:

  • 从列名PropertyA等周围取出单引号

标签: sql-server pivot pivot-table


【解决方案1】:

--去掉单引号你会得到想要的结果集

;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

您可以使用 Dynamic Pivot 生成相同的结果集。如下所示

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)

【讨论】:

  • 感谢您提供包括动态解决方案在内的全面解答!
【解决方案2】:

去掉引号。

SELECT * 
  FROM 
  ( 
  SELECT [PId], [CustomColumnName], [CustomColumnValue] 
  FROM [myTable]
  ) AS src
  PIVOT
  (MAX([CustomColumnValue])
   FOR [CustomColumnName] IN ([PropertyA], [PropertyB], [PropertyC], [PropertyD])
  ) AS pvt
GO
标识符 |物业A |物业B |物业C |属性D --: | :-------- | :-------- | :-------- | :-------- 1 | 1 |乙| C | 2 | 1.5 | BB |抄送 | 3 | 2.0 | | | D1

dbfiddle here

【讨论】:

  • 谢谢!!删除单引号并将它们视为列名有效!我接受了另一个答案,因为他/她还提供了动态列的解决方案。希望你能理解。 :)
【解决方案3】:

您需要使用列的引号名称

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

【讨论】:

  • 谢谢!!删除单引号并将它们视为列名有效!我接受了另一个答案,因为他/她还提供了动态列的解决方案。希望你能理解。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2015-08-19
  • 2021-09-18
  • 2013-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多