Select 动态SQL使用UNPIVOT选择列名和相关数据

Select 动态SQL使用UNPIVOT选择列名和相关数据,select,sql-server-2008-r2,unpivot,columnname,Select,Sql Server 2008 R2,Unpivot,Columnname,我有一个名为PersonnelServiceLevel的表,其中包含ID和名称等常规信息,但也有许多列标识为ServiceLevel%,如下所示: Person_ID Last_Name First_Name ServiceLevel1 ServiceLevel2 ServiceLevel3 etc. --------- --------- ---------- ------------- ------------- ------------- 222 Doe

我有一个名为PersonnelServiceLevel的表,其中包含ID和名称等常规信息,但也有许多列标识为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

谢谢。

要将列转换为行,可以说,您可以使用联合,如中所示:

我在这里使用UNIONALL是因为union也隐式地运行一个不同的操作,这在这里是不必要的


您也可以使用来执行此类操作。

您能告诉我们您使用的是什么RDBMS吗?该表是从Excel电子表格中导入的,其中可能有50到100列。是否有办法不别名或显式定义列名输出,例如Servicelevel1、ServiceLevel2等,而是列出由信息\u schema.columns定义的列名?从information_schema.columns中选择[column_name],其中table_name='PERSONNELSERVICELEVELS',这将不那么简单,但您可以使用系统目录和动态SQL动态构建查询。在旋转的情况下,这通常是有意义的,因为您可能事先不知道列的数量。然而,通过取消激活,您似乎知道要为哪些列创建行。即使调用information_schema,您也必须定义where子句来选择这些列名。感谢您为我指明了正确的方向。我确实有一个where子句,使用unpivoting得到了我想要的东西。语法如下:声明@cname nvarcharmax SELECT@cname=STUFFSELECT',“+CAST”['+[COLUMN_NAME]+']”为来自information_schema.columns的VARCHARMAX,其中表_NAME='PersonnelServiceLevel'和列_NAME,如XML路径的'ServiceLevel%',TYPE.value','VARCHARMAX',1,1,声明@sql nvarcharmax set@sql='从选择人员ID、姓氏、姓氏、服务级别、级别中选择人员ID、姓氏、姓氏、姓氏,'+@cname+'从PERSONNELSERVICELEVELS中选择人员ID、姓氏、服务级别,'+@cname+'作为MyUnPivot'执行sp_executesql@sql
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.