简体   繁体   English

使用 PIVOT 将 SQL 服务器中的 200 多行转换为列

[英]Converting 200+ rows to column in SQL Server using PIVOT

I have done some research and so far, this one makes sense to me:我已经做了一些研究,到目前为止,这对我来说很有意义:

Convert row value in to column in SQL server (PIVOT) 在 SQL 服务器 (PIVOT) 中将行值转换为列

However, I am wondering if there is any way to do this without having to declare the needed columns one by one, as I have more than 200 columns to retrieve.但是,我想知道是否有任何方法可以做到这一点而不必一一声明所需的列,因为我有 200 多个列要检索。

Here's a sneak peek of what I have as a table:这是我作为桌子的一瞥:

ID   | Col_Name   | Col_Value    
------------------------------
1    | Item_Num   | 12345
2    | Item_Date  | 34567
3    | Item_Name  | 97454
4    | Item_App1  | 234567
5    | Item_App2  | 345678

Take note that I have 200+ distinct values for Col_Name and I want it to be Column fields.请注意,我有 200 多个不同的 Col_Name 值,我希望它是 Column 字段。

I am using this one as of now but only for 5 columns:我现在正在使用这个,但只用于 5 列:

SELECT * FROM 
(
   SELECT [ID], [Col_Name], [Col_Value] 
   FROM myTable
) AS a 
PIVOT 
(
   MAX([Col_Value])
   FOR [Col_Name] in ([Item_Num], [Item_Date], [Item_Name], [Item_App1], [Item_App2])
) AS p 
ORDER BY [ID]

Is there any way this could be done considering the performance?考虑到性能,有什么办法可以做到这一点? Thanks in advance.提前致谢。

You can use dynamic sql to create the list of col_name:您可以使用动态 sql 创建 col_name 列表:

declare @pivot_col varchar(max);
declare @sql       varchar(max);
select  @pivot_col = string_agg( cast(col_name as varchar(max)), ', ') within group ( order by col_name ) from ( select distinct col_name from tmp_table ) A;

set @sql = 'SELECT * 
            FROM   (
                      SELECT [ID], [Col_Name], [Col_Value] 
                      FROM tmp_table
                   ) AS a 
                   PIVOT 
                   (
                      MAX([Col_Value])
                      FOR [Col_Name] in (' +  @pivot_col + ' )
                   ) AS p 
                   ORDER BY [ID]';
exec ( @sql );

The PIVOT / UNPIVOT operators are built on the principles of an Entity Attribute Value model (EAV). PIVOT / UNPIVOT 运算符建立在实体属性值 model (EAV) 的原则之上。 The idea behind an EAV model is that you can extend database entities without performing database schema changes. EAV model 背后的想法是您可以扩展数据库实体而无需执行数据库架构更改。 For that reason an EAV model stores all attributes of an entity in one table as key/value pairs.因此,EAV model 将实体的所有属性作为键/值对存储在一个表中。

If that is the idea behind your design then use the dynamic sql query i posted above, otherwise use a regular record with 200+ columns for each id, as suggested by Gordon.如果这是您设计背后的想法,请使用我在上面发布的动态 sql 查询,否则按照 Gordon 的建议,使用每个 id 包含 200 多列的常规记录。

You can read about the performance of PIVOT / UNPIVOT operatorshere .您可以在此处了解 PIVOT/UNPIVOT 运算符的性能。

EDIT: For sql server 2016 version:编辑:对于 sql 服务器 2016 版本:

declare @pivot_col varchar(max);
declare @sql       varchar(max);
select  @pivot_col = STUFF( (SELECT ',' + CAST(col_name AS VARCHAR(max)) AS [text()] FROM ( select distinct col_name from tmp_table ) A ORDER BY col_name FOR XML PATH('')), 1, 1, NULL);

set @sql = 'SELECT * 
            FROM   ( SELECT [ID], [Col_Name], [Col_Value] 
                     FROM tmp_table
                   ) AS a 
                   PIVOT 
                   (
                      MAX([Col_Value])
                      FOR [Col_Name] in (' +  @pivot_col + ' )
                   ) AS p 
                   ORDER BY [ID]';
exec ( @sql );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM