【问题标题】:SQL Grouping by intervals, counting and summingSQL按间隔分组,计数和求和
【发布时间】:2019-12-26 11:54:39
【问题描述】:

我需要找到在 Microsoft 服务器 SQL/T-SQL 中具有 15-20 年和超过 20 年工作经验的员工的总销售额。

我有一个看起来像这样的数据集:

    Hiredate       EmployeeID     Sales
0   1986-01-02     90             20,000
1   1989-02-30     80             10,000  
2   2000-01-20     91             50,000
3   2009-05-07     92             60,000
4   2007-07-06     47             30,000
5   1999-01-24     66             44,000
6   2005-09-22     21             30,000

到目前为止我所做的是:

   SELECT SUM(EmployeeID) 
   FROM (
   SELECT DATEDIFF(year,Hiredate, GETDATE()), COUNT(EmployeeID)
   FROM abc.table
   WHERE DATEDIFF(year, Hiredate, GETDATE()) > 20
   GROUP BY DATEDIFF(year,Hiredate, GETDATE())
   )

这部分给了我日期和员工人数的差异,但我不知道如何分开组然后总结销售额。

   SELECT DATEDIFF(year,Hiredate, GETDATE()), COUNT(EmployeeID)
   FROM abc.table
   WHERE DATEDIFF(year, Hiredate, GETDATE()) > 20
   GROUP BY DATEDIFF(year,Hiredate, GETDATE())

谢谢

【问题讨论】:

    标签: sql sql-server group-by


    【解决方案1】:

    您可以使用条件聚合:

    select
        sum(case 
            when datediff(year, hiredate, getdate()) between 15 and 20 
            then sales 
            else 0 
        end) sales_15_20,
        sum(case 
            when datediff(year, hiredate, getdate()) > 20 
            then sales 
            else 0 
        end) sales_above_20
    from mytable
    

    此查询将为您提供包含两列的唯一记录,其中包含每个条件的销售额总和。

    按照 Gordon Linoff 的以下建议,更优化的表述方式是:

    select
        sum(case 
            when hiredate 
                between dateadd(year, -20, getdate()) and dateadd(year, -15, getdate())
            then sales 
            else 0 
        end) sales_15_20,
        sum(case 
            when hiredate < dateadd(year, -20, getdate()) 
            then sales 
            else 0 
        end) sales_above_20
    from mytable
    

    【讨论】:

      【解决方案2】:

      不要使用datediff()——它不会达到你的预期。它计算两个日期之间的“边界”数量。对于年份,即 12 月 31 日至 1 月 1 日之间的午夜。

      此外,在列上应用函数通常会使创建最佳执行计划变得更加困难。

      你似乎想要:

      SELECT SUM(SALES) 
      FROM abc
      WHERE HireDate >= DATEADD(year, -20, GETDATE()) AND
            HireDate < DATEADD(year, -14 GETDATE());
      

      要获取两个组的值,一种方法是条件聚合:

      SELECT SUM(CASE WHEN HireDate >= DATEADD(year, -20, GETDATE()) AND
                           HireDate < DATEADD(year, -14 GETDATE())
                      THEN SALES
                 END),
              SUM(CASE WHEN HireDate < DATEADD(year, -20, GETDATE()) 
                       THEN SALES
                 END)
      FROM abc;
      

      另一种是将值放在行中:

      SELECT grp, SUM(sales)
      FROM abc CROSS APPLY
           (VALUES (CASE WHEN HireDate < DATEADD(year, -20, GETDATE()) THEN '20+ YEARS'
                         WHEN HireDate < DATEADD(year, -14, GETDATE()) THEN '15-20 YEARS'
                         ELSE '< 15 YEARS'
                    END)
           ) v(grp)
      GROUP BY grp
      ORDER BY MIN(HIREDATE);
      

      【讨论】:

        猜你喜欢
        • 2021-01-03
        • 2016-04-15
        • 1970-01-01
        • 2020-04-10
        • 2016-09-21
        • 1970-01-01
        • 2023-01-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多