SQL Server 2016将某些数据从行转移到列

时间:2017-02-17 13:12:33

标签: sql tsql sql-server-2016

我正在使用代码将特定数据从行转换为列,当我在一个小样本中使用它时它工作正常但是对于大约340万行的原始样本它会回复:

  

Msg 511,Level 16,State 1,Line 2
  无法创建大小为36912的行,该行大于允许的最大行大小8060。

(更多详情请见:) SQL Server 2008: Rows into columns in a dynamic way "HELP" with the code

代码:

        declare @sql nvarchar(max);
        declare @fields nvarchar(max);

        set @fields=stuff((select ',['+column0+']'
               from dll_ptbv
               where column0 not in ('Code','Mnemonic')
               group by column0
               order by case when column0='Name' then 0 else 3 end
               ,column0
               for xml path('')
              ,type
               ).value('.','nvarchar(max)')
               ,1 ,1 ,'');
      set@sql='select'+@fields 
         + 'from (select column0
                        ,column1
                        ,sum(rn1*rn2) over(order by rn2) as rn
                 from (select column0
                             ,column1
                             ,case when column0=''Name'' then 1 else 0 end as rn1
                             ,row_number() over(order by (select null)) as rn2
                     from dll_ptbv
                     ) as a
                ) as a
     pivot (max(column1) for column0 in ('+@fields+')) as p
     order by [Name]';
      execute sp_executesql @sql;

Small sample results

1 个答案:

答案 0 :(得分:1)

TL; DR解决方案不是在您的脚本中使用order by

您的问题是您正在尝试订购超过8060字节数据的行(source)。

  

每个GROUP BY的字节数,ORDER BY 8,060

我已经编写了一些代码来试用你的东西。

正如预期的那样,当我们发表评论order by [Name]

时,它会起作用
DROP TABLE IF EXISTS dll_ptbv

CREATE TABLE dll_ptbv(
ID INT IDENTITY(1,1)
,column0 NVARCHAR(MAX)
,column1 NVARCHAR(MAX)
 )

INSERT dll_ptbv VALUES ('Name', 'Very very company name')

-- generate dates and insert into table
DECLARE @start DATE, @end DATE;
SELECT @start = '20000101', @end = '20021201';

;WITH n AS 
(
SELECT TOP (DATEDIFF(DAY, @start, @end) + 1) 
n = ROW_NUMBER() OVER (ORDER BY [object_id])
  FROM sys.all_objects

)
INSERT dll_ptbv
SELECT DATEADD(DAY, n-1, @start), ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT))
FROM n;

SELECT TOP 10 * FROM dll_ptbv

 DECLARE @sql nvarchar(max);
 DECLARE @fields nvarchar(max);

    set @fields=stuff((select ', ['+column0+']'
           from dll_ptbv
           where column0 not in ('Code','Mnemonic')
           group by column0
           order by case when column0='Name' then 0 else 3 end
           ,column0
           for xml path('')
          ,type
           ).value('.','nvarchar(max)')
           ,1 ,1 ,'');
  SET @sql='select'+@fields 
     + 'from (select column0
                    ,column1
                    ,sum(rn1*rn2) over(order by rn2) as rn
             from (select column0
                         ,column1
                         ,case when column0=''Name'' then 1 else 0 end as rn1
                         ,row_number() over(order by (select null)) as rn2
                 from dll_ptbv
                 ) as a
            ) as a
 pivot (max(column1) for column0 in ('+@fields+')) as p
 --order by [Name]
 ';

  PRINT @SQL
  EXECUTE sp_executesql @sql;