【问题标题】:Dynamic SQL SELECT column names and related data using UNPIVOT使用 UNPIVOT 的动态 SQL SELECT 列名和相关数据
【发布时间】:2012-11-14 17:26:11
【问题描述】:

我有一个名为PERSONNELSERVICELEVELS 的表,其中包含IDName 等一般信息,但也有许多列标识为ServiceLevel%,如下所示:

Person_ID  Last_Name  First_Name  ServiceLevel1  ServiceLevel2  ServiceLevel3  etc.
---------  ---------  ----------  -------------  -------------  -------------
222        Doe        John        4              5              NULL  
555        Doe        Jane        2              6              9

我想创建一个SELECT 语句来产生这个输出:

Person_ID  Last_Name  First_Name  ServiceLevel  Level
---------  ---------  ----------  ------------  ----- 
222        Doe        John        ServiceLevel1 4
222        Doe        John        ServiceLevel2 5
222        Doe        John        ServiceLevel3 NULL
555        Doe        Jane        ServiceLevel1 2
555        Doe        Jane        ServiceLevel2 6
555        Doe        Jane        ServiceLevel3 9

谢谢。

【问题讨论】:

  • 您能告诉我们您使用的是什么 RDBMS 吗?

标签: select sql-server-2008-r2 unpivot columnname


【解决方案1】:

可以说,要将列转换为行,您可以使用UNION,如下所示:

select Person_ID, Last_Name, First_Name, 'ServiceLevel1' as ServiceLevel, ServiceLevel1 as [Level]
from PERSONNELSERVICELEVELS
union all
select Person_ID, Last_Name, First_Name, 'ServiceLevel2' as ServiceLevel, ServiceLevel2 as [Level]
from PERSONNELSERVICELEVELS
union all
-- etc.

我在这里使用union all,因为联合也隐式运行了一个不同的操作,而这在这里是不必要的。

你也可以用UNPIVOT做这种事情。

【讨论】:

  • 表格是从 Excel 电子表格导入的,其中可能有 50 到 100 列。有没有办法不使用别名或显式定义列名输出(例如 Servicelevel1、ServiceLevel2 等),而是列出由 information_schema.columns 定义的 column_name?从 information_schema.columns 中选择 [column_name] 其中 table_name = 'PERSONNELSERVICELEVELS'
  • 它不会那么简单,但您可以使用系统目录和动态 SQL 来动态构建查询。在透视的情况下,这通常是有意义的,因为您可能事先不知道列数。但是,通过反透视,您似乎知道要为哪些列创建行。即使调用 information_schema,您也必须定义 where 子句来选择这些列名。
  • 感谢蒂姆带领我朝着正确的方向前进。我确实有一个 where 子句,并且使用 unpivoting 得出了我正在寻找的东西。语法如下:
  • declare @cname nvarchar(max) SELECT @cname = STUFF((SELECT ', ' +CAST('['+[COLUMN_NAME]+']' AS VARCHAR(MAX)) FROM information_schema.columns where table_name = 'PERSONNELSERVICELEVELS' and column_name like 'ServiceLevel%' FOR XML PATH(''), TYPE).value('.', 'varchar(max)') ,1,1,'') declare @sql nvarchar(max) set @sql = 'SELECT Person_ID, Last_Name, First_Name, ServiceLevel, Level FROM ( SELECT Person_ID, Last_Name, First_Name, '+@cname+' FROM PERSONNELSERVICELEVELS ) MyTable UNPIVOT (Level FOR ServiceLevel IN ('+@cname+'))AS MyUnPivot' exec sp_executesql @sql
猜你喜欢
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
  • 2015-06-30
  • 2016-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多