【问题标题】:Pivoting Varchar Value to column将 Varchar 值旋转到列
【发布时间】:2021-03-24 15:01:48
【问题描述】:

我正在尝试在 SQL Server 2016 中转换此数据集

--数据集

CarModel    Tire              MakeDate   Owner

Subaru       MRF             20200101     John D
Subaru       Goodyear        20200101     John D
Subaru       MRF             20200101     John D
Subaru       MRF             20200101     John D

输出结果应该是:

CarModel Tire1 Tire2     Tire3 Tire4 MakeDate    Owner
Subaru   MRF   GoodYear  MRF    MRF   20200101    John D

我试过了,但没有成功。如果我犯了任何错误,请告诉我吗?

create table #temp_Dataset 
(Carmodel varchar(10), Tire varchar(10), MakeDate int, [Owner] Varchar(10))

insert into #temp_Dataset
(Carmodel, Tire, MakeDate, [Owner])
values 
('Subaru',       'MRF',             20200101 ,    'John D'),
('Subaru',       'Goodyear',        20200101 ,    'John D'),
('Subaru',       'MRF',             20200101 ,    'John D'),
('Subaru',       'MRF',             20200101 ,    'John D')

Select * from( 
 SELECT CarModel,
       Tire,
       MakeDate,
       [Owner]
FROM #temp_Dataset)a
pivot (max(carmodel) for Tire in (Tire1, Tire2, Tire3, Tire4))piv

drop table #temp_Dataset

【问题讨论】:

    标签: sql sql-server pivot sql-server-2016


    【解决方案1】:

    您错过了枚举轮胎并在 MAX 聚合中使用了错误的参数 ([Carmodel])。更喜欢使用诸如

    SELECT * 
      FROM( 
           SELECT *,
                  CONCAT('Tire',ROW_NUMBER() OVER 
                 (PARTITION BY [Carmodel], [MakeDate], [Owner] ORDER BY [CarModel])) AS [rn]
             FROM #temp_Dataset
          ) AS ds
      PIVOT(
            MAX([Tire]) FOR [rn] IN ([Tire1],[Tire2],[Tire3],[Tire4])
           ) AS piv
    

    顺便说一句,在当前情况下,四个轮胎将任意排序,您可以通过更改ORDER BY 子句中的列来随意更改。

    您甚至可以使旋转动态化,以便在按其他列分组时添加或减去轮胎的值,例如

    DECLARE @cols  AS NVARCHAR(MAX),  @query AS NVARCHAR(MAX)
                    
    SELECT @cols = 
           STUFF((SELECT DISTINCT ',' + QUOTENAME(CONCAT('Tire',[rn])) AS formulas
                    FROM 
                    (
                     SELECT *, 
                            ROW_NUMBER() OVER 
                            (PARTITION BY [Carmodel], [MakeDate], [Owner] ORDER BY [CarModel]) AS rn
                       FROM [#temp_Dataset]
                    ) ff
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'');
            
    SET  @query =
              N'SELECT * 
                  FROM( 
                       SELECT *,
                              CONCAT(''Tire'',
                              ROW_NUMBER() OVER (PARTITION BY [Carmodel], [MakeDate], [Owner] ORDER BY [CarModel])) AS [rn]
                         FROM [#temp_Dataset]
                      ) AS ds
                 PIVOT(
                       MAX([Tire]) FOR [rn] IN (' + @cols + N' )
                      ) AS piv'
    
    EXEC sp_executesql @query;
    

    Demo

    【讨论】:

      【解决方案2】:

      你可以使用条件聚合和row_number():

      select carmodel, makedate, owner,
             max(case when seqnum = 1 then tire end) as tire_1,
             max(case when seqnum = 2 then tire end) as tire_2,
             max(case when seqnum = 3 then tire end) as tire_3,
             max(case when seqnum = 4 then tire end) as tire_4
      from (select t.*,
                   row_number() over (partition by carmodel, makedate, owner order by ?) as seqnum
            from #temp_Dataset t
           ) t
      group by carmodel, makedate, owner;
      

      ? 用于列的排序。您希望结果的顺序并不明显——SQL 表表示 无序 集。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-08
        • 2021-09-15
        • 2016-06-16
        • 2011-03-08
        • 2013-09-08
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        相关资源
        最近更新 更多