【问题标题】:SQL Server 2016 transpose certain data from row to columnSQL Server 2016 将某些数据从行转置到列
【发布时间】:2017-02-20 15:02:17
【问题描述】:

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

消息 511,第 16 级,状态 1,第 2 行
无法创建大于允许的最大行大小 8060 的大小为 36912 的行。

(更多细节在这里:)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;

【问题讨论】:

  • 您是否要在任何地方插入您的结果?
  • “插入..任何地方”是什么意思?
  • 我的意思是您将它们插入到表中(临时或永久)。此错误通常是由于尝试插入 IN_ROW_DATA 超过 8kb 的行引起的
  • 我正在将它插入一个永久的!
  • 那是你的问题,你的列太多了。为什么要以这种方式对数据进行非规范化?

标签: sql tsql sql-server-2016


【解决方案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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2015-06-18
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多