SQL Server实现列转行

今天介绍4种列转行(又称宽表转长表、逆透视等)写法。
在这里插入图片描述

数据准备

CREATE TABLE Sales([Year] INT,Q1 INT,Q2 INT,Q3 INT,Q4 INT);
GO
INSERT INTO Sales([Year],Q1,Q2,Q3,Q4)
    VALUES (2017,12,123,324,123)
          ,(2018,13,455,324,878)
          ,(2019,29,786,473,633);

   
   

    SQL写法

    UNION

    最传统最通用写法

    SELECT [Year],'Q1' AS [Quarter],Q1 AS Amount FROM Sales UNION ALL
    SELECT [Year],'Q2' AS [Quarter],Q2 AS Amount FROM Sales UNION ALL
    SELECT [Year],'Q3' AS [Quarter],Q3 AS Amount FROM Sales UNION ALL
    SELECT [Year],'Q4' AS [Quarter],Q4 AS Amount FROM Sales; 
    
       
       
      UNPIVOT

      unpivot 的独特语法:

      SELECT [Year],[Quarter],[Amount]
      FROM Sales AS a
      UNPIVOT(Amount FOR [Quarter] IN (Q1,Q2,Q3,Q4)) AS b;
      
         
         
        CROSS JOIN

        其实就是笛卡尔积,用CROSS JOIN是MSSQL的推荐写法,其它数据库若不支持此语法,可以将CROSS JOIN替换为逗号,或用Join On 1 = 1

        SELECT a.[Year],b.[Quarter]
              ,CASE b.[Quarter] 
                   WHEN 'Q1' THEN Q1
                   WHEN 'Q2' THEN Q2
                   WHEN 'Q3' THEN Q3
                   WHEN 'Q4' THEN Q4
               END AS Amout
        FROM Sales a
        CROSS JOIN (VALUES ('Q1'),('Q2'),('Q3'),('Q4')) AS b([Quarter]);
        
           
           
          CROSS APPLY

          CROSS APPLY是个强大的操作符,也可以用来实现unpivot:

          SELECT a.[Year], b.[Quarter],b.Amount
          FROM Sales a
          CROSS APPLY (SELECT 'Q1' AS [Quarter],a.Q1 AS Amount UNION ALL 
                       SELECT 'Q2',a.Q2 UNION ALL 
                       SELECT 'Q3',a.Q3 UNION ALL 
                       SELECT 'Q4',a.Q4) AS b;
          -- 或
          SELECT a.[Year], b.[Quarter],b.Amount
          FROM Sales a
          CROSS APPLY (VALUES ('Q1',a.Q1)
                             ,('Q2',a.Q2)
                             ,('Q3',a.Q3)
                             ,('Q4',a.Q4)) AS b([Quarter],Amount);
          
             
             

            总结与说明

            • 传统的Union写法需要扫描多次基表,效率最差
            • UNPIVOT写法最简洁,而且执行效率高,但语法有点晦涩,不是SQL的典型风格
            • CROSS JOIN与CROSS APPLY写法也只要扫描一次基表,可能执行效率比UNPIVOT差一点点,但好处是语法上更灵活
            评论 2
            添加红包

            请填写红包祝福语或标题

            红包个数最小为10个

            红包金额最低5元

            当前余额3.43前往充值 >
            需支付:10.00
            成就一亿技术人!
            领取后你会自动成为博主和红包主的粉丝 规则
            hope_wisdom
            发出的红包
            实付
            使用余额支付
            点击重新获取
            扫码支付
            钱包余额 0

            抵扣说明:

            1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
            2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

            余额充值