【问题标题】:Unpivot table data反透视表数据
【发布时间】:2014-07-07 12:19:46
【问题描述】:
 Sno    Water   Milk
  1      50     100
  2      22     120
  3      11     142

我有这张桌子。现在我想要类似的结果

  Sno   Type   Qnty
   1    Water   83
   2     Milk   362

我该怎么告诉我。

【问题讨论】:

  • 为什么Sno 1 代表水,2 代表牛奶?这个选择背后有什么逻辑还是只是一个任意的行号?
  • 只是行号

标签: sql-server sql-server-2005 stored-procedures unpivot


【解决方案1】:

SQL Server 2008 不支持这种语句。

您可以通过两种方式实现:

使用临时表(变量类型表) DECLARE @products TABLE(Sno INT, Water INT, Milk INT)

 INSERT INTO @products
 VALUES (1, 50, 100), (2, 22, 120), (3, 11, 142)


 SELECT ROW_NUMBER() OVER(ORDER BY SUM(Qnty)) AS RowNo, Product, SUM(Qnty) AS Qnty
 FROM (
  SELECT Product, Qnty
 FROM (
    SELECT *
    FROM @products
     ) AS pvt
 UNPIVOT (Qnty FOR Product IN ([Water],[Milk])) AS unpvt
 ) AS T
 GROUP BY Product</pre>

;WITH T AS
 (
 SELECT Sno, Water, Milk
  FROM (
  SELECT 1 AS Sno, 50 AS Water, 100 AS Milk
  UNION ALL
  SELECT 2, 22, 120
  UNION ALL
  SELECT 3, 11, 142
  ) t (Sno, Water, Milk))
   SELECT  Sno = ROW_NUMBER() OVER(ORDER BY SUM(Upvt.Qnty)),
    upvt.Type,
    Qnty = SUM(Upvt.Qnty)
    FROM    T
   UNPIVOT
    (   Qnty
        FOR Type IN ([Water], [Milk])
    ) upvt
   GROUP BY upvt.Type
   ORDER BY Qnty;</pre>

   Please,refer MSDN documentation.

【讨论】:

    【解决方案2】:

    第一步是UNPIVOT你的数据:

    WITH T AS
    (   SELECT Sno, Water, Milk
        FROM (VALUES (1, 50, 100), (2, 22, 120), (3, 11, 142)) t (Sno, Water, Milk)
    )
    SELECT  upvt.Sno,
            upvt.Type,
            Upvt.Qnty
    FROM    T
            UNPIVOT
            (   Qnty
                FOR Type IN ([Water], [Milk])
            ) AS upvt;
    

    这将给:

    Sno Type    Qnty
    1   Water   50
    1   Milk    100
    2   Water   22
    2   Milk    120
    3   Water   11
    3   Milk    142
    

    然后您可以对该结果应用普通聚合:

    WITH T AS
    (   SELECT Sno, Water, Milk
        FROM (VALUES (1, 50, 100), (2, 22, 120), (3, 11, 142)) t (Sno, Water, Milk)
    )
    SELECT  Sno = ROW_NUMBER() OVER(ORDER BY SUM(Upvt.Qnty)),
            upvt.Type,
            Qnty = SUM(Upvt.Qnty)
    FROM    T
            UNPIVOT
            (   Qnty
                FOR Type IN ([Water], [Milk])
            ) AS upvt
    GROUP BY upvt.Type
    ORDER BY Qnty;
    

    给予:

    Sno Type    Qnty
    1   Water   83
    2   Milk    362
    

    编辑

    根据您的评论,您使用的是 SQL Server 2005,而不是 2008,如下所示是一个完整的工作示例,将在 2005 上工作:

    DECLARE @T TABLE (Sno INT, Water INT, Milk INT);
    INSERT @T (Sno, Water, Milk) VALUES (1, 50, 100);
    INSERT @T (Sno, Water, Milk) VALUES(2, 22, 120);
    INSERT @T (Sno, Water, Milk) VALUES(3, 11, 142);
    
    SELECT  Sno = ROW_NUMBER() OVER(ORDER BY SUM(Upvt.Qnty)),
            upvt.Type,
            Qnty = SUM(Upvt.Qnty)
    FROM    @T AS T
            UNPIVOT
            (   Qnty
                FOR Type IN ([Water], [Milk])
            ) AS upvt
    GROUP BY upvt.Type
    ORDER BY Qnty;
    

    在 2005 年,我用来创建示例数据的表值构造函数导致错误,与取消透视然后对数据求和的实际查询无关。

    【讨论】:

    • 它给出了这样的错误“关键字'VALUES'附近的语法不正确。”
    • 您使用的是 SQL Server 2005 吗?
    • 那么你所做的与我发布的内容不同。它在我的 SQL Server 2008 版本和 SQL Fiddle 上运行良好
    • 运行SELECT @@VERSION会得到什么结果?
    • Microsoft SQL Server 2005 - 9.00.1399.06(Intel X86)2005 年 10 月 14 日 00:33:37 版权所有 (c) 1988-2005 Microsoft Corporation Enterprise Edition on Windows NT 5.2(Build 3790:Service Pack 2 )
    【解决方案3】:

    这给出了您要求的结果,但我知道您想要更高级的东西。如果有,请详细说明。

    SELECT 'water', sum(water) FROM table_name
    UNION ALL 
    SELECT 'milk', sum(milk) FROM  table_name
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-20
      • 2022-08-18
      • 1970-01-01
      • 2021-06-10
      • 2022-11-12
      • 2018-04-10
      • 2013-02-21
      • 1970-01-01
      相关资源
      最近更新 更多