使用数据透视的动态列

Posted

技术标签:

【中文标题】使用数据透视的动态列【英文标题】:Dynamic columns using pivot 【发布时间】:2020-12-30 07:43:52 【问题描述】:

我有一张如下所示的表格:

主表

id bomname styleid
1 bom1 101
2 bom2 102
3 bom3 103

这是明细表

Id bomId bomKey bomValue
1 1 part cllr
2 1 unit kg
3 1 qty 123
4 1 part body
5 1 unit kg
6 1 qty 456
7 2 part slm
8 2 unit kg
9 2 qty 789
10 3 part abc
11 3 unit kg
12 3 qty 789
13 3 color red

我希望查询 styleid=101 使用 PIVOT 显示此数据列表:

part unit qty ids
cllr kg 123 [1,2,3]
body kg 456 [4,5,6]

我希望查询 styleid=103 使用 PIVOT 显示此数据列表:

part unit qty color ids
abc kg 789 red [10,11,12,13]

这是我的 SQL 代码:

DECLARE @sql nvarchar(max) = '', @col_list nvarchar(max) = ''

SET @col_list = (SELECT DISTINCT QUOTENAME(bomKey) + ','  
                 FROM BomDetail 
                 FOR XML PATH(''))

SET @col_list = LEFT(@col_list, LEN(@col_list) - 1)

SET @sql = 'SELECT ' + @col_list + 
           ' FROM
                 (SELECT bomKey, bomValue FROM BomDetail) x
             PIVOT
                 (MAX([bomValue]) FOR [bomKey] IN (' + @col_list + ')
            ) AS p'

EXEC(@sql)

但是现在查询只返回一行数据,如何修改我的SQL代码?

part unit qty
body kg 456

【问题讨论】:

在您的执行官之前添加print @sql 并发布您的结果 对于styleid=103qty 应该是789 对吧? @Squirrel 是的,我已经修复了 【参考方案1】:

请试试这个!

DECLARE @sql nvarchar(max) = '', @col_list nvarchar(max) = ''

SET @col_list = (SELECT DISTINCT QUOTENAME(a.bomKey) + ','  
                 FROM DetailTable a join MainTable b on (a.bomId = b.id)
                 where b.styleid=101 --> CHANGE IT
                 FOR XML PATH(''))

SET @col_list = LEFT(@col_list, LEN(@col_list) - 1)

If Object_id('Tempdb..#Details') is not null
    Drop Table #Details

Create Table #Details (Seq Int, bomId Int,bomkey varchar(20), bomvalue varchar(20),id Int)

Insert #Details
select Row_Number() Over(Partition by d.bomkey Order by d.bomkey) Seq, d.bomId,d.bomkey, d.bomvalue,d.id 
from DetailTable d join MainTable m
on (d.bomId = m.id)
where styleid=101   --> CHANGE IT
Order by 1


SET @sql = 'SELECT ' + @col_list + 
           ',Ids FROM
                 (select bomkey, bomvalue, ''['' + stuff((select '','' + cast(id as varchar(100))  from #Details b where b.seq = a.seq for xml path('''')),1,1,'''') + '']'' Ids from #Details a ) x
             PIVOT
                 (MAX([bomvalue]) FOR [bomKey] IN ('+@col_list+')
            ) AS p'

EXEC(@sql)

注意:

    在此代码的两个地方替换 StyleId 相应地替换为 MainTableDetailTable

【讨论】:

谢谢,您的解决方案彻底解决了我的问题,非常感谢!

以上是关于使用数据透视的动态列的主要内容,如果未能解决你的问题,请参考以下文章

具有动态列的 MySQL 数据透视表查询

具有动态列的 MySQL 数据透视表查询

SQL 动态数据透视表列顺序

SQL Server 中具有动态列的数据透视表

未知数量列的 SQL Server 动态数据透视

透视动态列,无聚合