首页 > 解决方案 > SQL:遍历表中的每个条目,并使用行名、列名和条目创建一个新条目

问题描述

我有一个名为“tb_Object”的 SQL Server 表,如下所示:

ObjektID    Name    ID1    ID2    ID3
----------------------------------------
     1      O1       1     2.30   0.002
     2      O2       2     3.40   0.004
     3      O3       1     2.10   0.200
...                  

我想将其转换为如下所示的表格:

PK_ID     ObjektID    Name       ColName
-----------------------------------------
  1         1         O1    1      ID1
  2         2         O2    2      ID1
  3         3         O3    1      ID1
... 
110         1         O1    2.30   ID2
111         2         O2    3.40   ID2
112         3         O3    2.10   ID2
...
220         1         O1    0.002  ID3
221         2         O2    0.004  ID3
222         3         O3    0.200  ID3
... 

我知道这在 Python 中很容易。但我不知道如何在 SQL/T-SQL 中做到这一点,特别是因为我不能使用索引。有谁知道如何以聪明的方式处理这个问题?

标签: sql-servertsql

解决方案


如果您的列数不是太多,您可以使用 UNION 语句将其转换为所需的格式:

;with cte as
(select 1 as ObjektID,'O1' as Name,1 as ID1,2.3 as ID2,0.002 as ID3 UNION
select 2 as ObjektID,'O2' as Name,2 as ID1,3.4 as ID2,0.004 as ID3 UNION
select 3 as ObjektID,'O3' as Name,1 as ID1,2.1 as ID2,0.200 as ID3)

select  row_number() over(order by Objektid,Name,ColName) as PK_ID,
        a.*
from
(select ObjektID,Name,'ID1' as ColName,ID1 as Value from cte
UNION
select ObjektID,Name,'ID2' as ColName,ID2 as Value from cte
UNION
select ObjektID,Name,'ID3' as ColName,ID3 as Value from cte) a

希望这可以帮助。

编辑:另一种方法是使用 UNPIVOT:

SELECT  row_number() over(order by ObjektId,ColumnName) as PK_ID,
        ObjektID, name, ColumnName, Value  
FROM   
   (select ObjektID,Name,ID1,ID2,ID3 from cte) p  
UNPIVOT  
   (Value FOR ColumnName IN   
      (ID1, ID2, ID3)) as unpvt;

推荐阅读