sql server中的动态数据库错误

时间:2014-12-26 11:47:02

标签: sql sql-server pivot

我使用了链接中的上述代码。但我收到一个错误

  

Msg 8156,Level 16,State 1,Line 14“Factory”栏目是   为'p'指定了多次

Efficiently convert rows to columns in sql server

这是我的表:

TEST

ID      score    Check      TotalofScore
------  -----    -------    ------------
867439  1        factory        1
867439  1        Plant          1
867442  1        factory        1
867442  1        Plant          1
923991  1        Warehouse      1
923991  1        Plant          1
923930  1        factory        1
923930  1        Plant          1
923101  1        Warehouse      1
923101  1        Plant          1

这是我的尝试

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

SELECT @cols = Stuff((SELECT ',' + Quotename([check])
                      FROM   TEST
                      GROUP  BY [Check],
                                [ID]
                      ORDER  BY [ID]
                      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SET @query = N'SELECT ' + @cols + N' from 
             (SELECT TEST.[ID],
                     Score,
                     [check],
                     [Total Of Score] = Count(TEST.Score) over(partition by [ID], [score], [check])
             FROM TEST) T
            pivot 
            (
             SUM (T.[score])
             for T.[check] in (' + @cols + N') ) p '

EXEC Sp_executesql @query; 

预期结果:

ID       TotalofScore   factory     Plant   Warehouse
------   ------------   -------     -----   ---------
867439      1             1 
867439      1                                   1
867442      1                       1
867442      1                                   1
923991      1             1 
923991      1             1
923930      1                       1
923930      1                       1
923101      1              1
923101      1                                   1

2 个答案:

答案 0 :(得分:1)

如错误中所述您无法在Pivot中多次指定相同的列名称,如

..pivot (SUM (T.[score]) for T.[check] in ([factory,[Plant],[factory]..))p

像这样更改@cols初始化

SELECT @cols = Stuff((SELECT DISTINCT ',' + Quotename([check])
                      FROM   TEST
                      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 

SELECT @cols = Stuff((SELECT ',' + Quotename([check])
                      FROM   TEST
                      GROUP  BY [Check]
                      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 

更新:将动态数据透视转换为过程并将结果插入新表

create procedure dbname.schemaname.DynamicPivotProcedure 
as
begin
DECLARE @cols  AS NVARCHAR(MAX),
        @query AS NVARCHAR(MAX)

SELECT @cols = Stuff((SELECT ',' + Quotename([check])
                      FROM   TEST
                      GROUP  BY [Check]
                      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SET @query = N'SELECT ID, [Total Of Score],' + @cols + N' from 
             (SELECT TEST.[ID],
                     Score,
                     [check],
                     [Total Of Score] = Count(TEST.Score) over(partition by [ID], [score], [check])
             FROM TEST) T
            pivot 
            (
             SUM (T.[score])
             for T.[check] in (' + @cols + N') ) p '

EXEC Sp_executesql @query; 
end

go
sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

IF OBJECT_ID('tempdb..#MyTempTable') IS NOT NULL 
begin
DROP TABLE #MyTempTable
end

SELECT * INTO #MyTempTable FROM 
OPENROWSET('SQLNCLI', 'Server=(local)\SQL2008;Trusted_Connection=yes;',
     'EXEC dbname.schemaname.DynamicPivotProcedure')

SELECT * FROM #MyTempTable

答案 1 :(得分:1)

IdGROUP BY子句中删除ORDER By。这样您就可以获得DISTINCT检查列。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME([check]) 
  from #Sample
  group by [Check]
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
set @query = N'SELECT  ID, [Total Of Score], ' + @cols + N'  from 
             (
               SELECT 
TEST.[ID],
Score,
[check],
[Total Of Score] = Count(TEST.Score) over(partition by [ID], [score], [check])
FROM #Sample AS TEST
  ) T
  pivot 
  (
     SUM (T.[score])
      for T.[check] in (' + @cols + N')
  ) p '
exec sp_executesql @query;