【问题标题】:How to group by records based on year in SQL server [duplicate]如何在SQL Server中根据年份按记录分组[重复]
【发布时间】:2016-06-30 16:20:52
【问题描述】:

我有一个名为 Product 的表格,它显示如下数据:

---------------------------------
l  TYPE   l PERIOD l  BALANCE   l
l   Auto  l  2015  l     5      l     
l   Car   l  2015  l     2      l     
l   Bus   l  2015  l     45     l   
l   Auto  l  2016  l     2      l     
l   Car   l  2016  l     6      l     
l   Bus   l  2016  l     50     l  
l   Auto  l  2017  l     12     l     
l   Car   l  2017  l     16     l     
l   Bus   l  2017  l     10     l  
---------------------------------

我需要查询此表,以便结果基于类似于下面的年份:

---------------------------------------------------------
l TYPE    l BALANCE 2015 l BALANCE 2016 l BALANCE 2017 l
l   Auto  l     5        l       2      l     12       l
l   Car   l     2        l       6      l     16       l
l   Bus   l     45       l       50     l     10       l
---------------------------------------------------------

我尝试了不同的查询,但没有运气。

您的帮助将非常有用,

提前致谢。

【问题讨论】:

  • 您可以在 MS Sql Server 中使用 PIVOT
  • MySQL 还是 MS SQL Server? (不同的产品,答案可能因产品而异。)
  • 如果突然插入 2014 行,是否会以某种方式包含在结果中?

标签: sql sql-server sql-server-2008


【解决方案1】:

您可以像这样使用条件聚合:

SELECT t.type,
       MAX(CASE WHEN period = 2015 then balance end) as BALANCE_2015,
       MAX(CASE WHEN period = 2016 then balance end) as BALANCE_2016,
       MAX(CASE WHEN period = 2017 then balance end) as BALANCE_2017
FROM Product t
GROUP BY t.type

您可以添加更多列,具体取决于您要显示的年份。

【讨论】:

  • 感谢您的查询,但我不确定“PERIOD”列将有多少年,因此我无法对 2015、2016、2017 期间的查询进行硬编码。是否可以修改此查询以从表中动态选择全年
【解决方案2】:
SELECT *
FROM (
    SELECT period, type, balance 
    FROM dbo.Product
) t
PIVOT (
    MAX(balance)
    FOR period IN ([2015], [2016], [2017]) 
) p

【讨论】:

    【解决方案3】:

    您可以尝试使用PIVOT

    select [Type],[2015] as BALANCE2015,[2016] as BALANce2016,[2017] as BALANCe2017 from 
    (
    select [Type],[Period],[Balance] from my_table
    ) as t
    pivot 
    (
    max([Balance]) for Period in ([2015],[2016],[2017])
    ) as pvt
    order by pvt.[Type]
    

    【讨论】:

      【解决方案4】:

      对于您的方案,由于“期间”是一个可以具有任何值的表列,因此上述硬编码值的方法不是一个好主意。

      您应该根据 Period 的值生成动态 PIVOT 查询。

      查看以下链接。

      http://www.codeproject.com/Tips/1011591/Dynamic-Pivot-Query-in-SQL-Server

      更新:

      以下查询是您所需要的。

      DECLARE @ColumnName AS VARCHAR(MAX)
      DECLARE @DynamicPivotQuery AS VARCHAR(MAX) = ''
      
      SELECT @ColumnName = COALESCE(@ColumnName + ',', '') + QUOTENAME(PERIOD)
              FROM (SELECT DISTINCT PERIOD FROM Product) T;
      
      SET @DynamicPivotQuery = N'SELECT [TYPE], ' + @ColumnName + ' FROM Product ' + 
                              ' PIVOT(SUM([BALANCE]) FOR PERIOD IN (' + @ColumnName + ')) AS PVTTable;';
      
      EXEC (@DynamicPivotQuery)
      

      注意:

      我在 PIVOT 中使用 SUM 作为聚合函数,您可以根据需要将其更改为 MAX 或 MIN。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-06
        • 2016-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-21
        相关资源
        最近更新 更多