【问题标题】:Flatten table rows into columns in SQL Server [duplicate]在 SQL Server 中将表行展平为列 [重复]
【发布时间】:2019-06-05 16:45:07
【问题描述】:

我有下面的 SQL 表,其中有随机生成的数据

  Code          Data
    SL Payroll    22
    SL Payroll    33
    SL Payroll    43
    ..            .....

我要传输数据,格式如下图

Code         Data1   Data2   Data3  ..
SL Payroll   22       33      43    ....  

有人建议使用数据透视表来转换数据,如下所示

SELECT Code,
       [22] Data1,
       [33] Data2,
       [43] Data3
FROM
    (
      SELECT *
      FROM T
    ) TBL
    PIVOT
    (
      MAX(Data) FOR Data IN([22],[33],[43])
    ) PVT

但这假设数据点是静态的,例如 22,33,但它们是动态生成的。

【问题讨论】:

  • 那是你的研究吗??? stackoverflow.com/q/54134488/6426692
  • Sami 我本身不是数据库开发人员,但我只需要为我的前端代码完成这个。我试着看,但很多例子都在做 AVG 或只是转置。我刚刚在那里看到了您的回答..非常感谢您的帮助..我实际上只是要做一些循环并插入更新技巧来实现结果,这不像您建议的 Pivot 东西那么酷,只是为了完成工作。时间紧迫,因此寻求帮助。

标签: sql-server tsql sql-server-2008 pivot sql-server-2014


【解决方案1】:

如果您知道或最大数量的所需列,您可以做一个简单的 PIVOT,否则,您需要 DYNAMIC

示例

 Select *
  From (
        Select [Code]
              ,[Data]
              ,[Col] = concat('Data',Row_Number() over (Partition By [Code] Order by 1/0))
         From  YourTable
       ) src
 Pivot (max([Data]) for [Col] in ([Data1],[Data2],[Data3],[Data4],[Data5])) pvt

退货

Code        Data1   Data2   Data3   Data4   Data5
SL Payroll  22      33      43      NULL    NULL

【讨论】:

  • 哇..非常好..非常感谢。
  • @user1221989 乐于助人。真正的魔力是 Row_Number()。花时间熟悉窗口功能是非常值得的。 :)
  • @JohnCappelletti OP 只需要一份简历,因为this
【解决方案2】:

我会使用条件聚合和row_number():

select code,
       max(case when seqnum = 1 then code end) as code_1,
       max(case when seqnum = 2 then code end) as code_2,
       max(case when seqnum = 3 then code end) as code_3
from (select t.*,
             row_number() over (partition by code order by data) as seqnum
      from t
     ) t
group by code;

【讨论】:

  • 谢谢 Gordon..非常感谢您的时间和帮助。
【解决方案3】:

做动态支点我很久以前就做过了。

更新:更接近您的代码和传奇名称。

这适用于 PIVOT 所需的任意多列,不管是 1 还是 20

DECLARE @SelectFieldNameList as varchar(8000)
DECLARE @SelectFieldNameListCount as varchar(8000)
Set @SelectFieldNameList = ''
Set @SelectFieldNameListCount = ''

-- this section selects the list of firm location names and puts them in a string to be used in the pivot
-- it does it for the field select list and the count select using ISNULL so it puts a 0 if no counts returned
SELECT top (999999) @SelectFieldNameList = @SelectFieldNameList + case when @SelectFieldNameList = '' then '' else ', ' end 
+ '[' + Data + ']', 
@SelectFieldNameListCount = @SelectFieldNameListCount + case when @SelectFieldNameListCount = '' then '' else ', ' end 
+ 'ISNULL([' + Data + '], ''0'')' + Data 
From TableName
Where Data IS NOT NULL AND Ltrim(Data) <> ''
Group by Data

-- just for testing
select @SelectFieldNameList, @SelectFieldNameListCount


-- NOW USE THE ABOVE TO get the data pivoted with your dyanic fields
EXEC('
SELECT [Code], ' + @SelectFieldNameListCount + '
FROM (  
    SELECT [Code], Data, Sum(CountTotal) as CountTotal
    From TableName
    Group by [Code], Data
) AS TableToBePivoted
PIVOT (  
    SUM(CountTotal) 
    FOR Data IN (' + @SelectFieldNameList + ')  
) AS PivotedTable
order by [Code];  
')

【讨论】:

  • 非常感谢布拉德的时间和努力 :)
猜你喜欢
  • 2015-07-01
  • 2015-04-10
  • 1970-01-01
  • 1970-01-01
  • 2015-02-11
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多