SQL按间隔分组,计数和求和
Posted
技术标签:
【中文标题】SQL按间隔分组,计数和求和【英文标题】:SQL Grouping by intervals, counting and summing 【发布时间】: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())
谢谢
【问题讨论】:
【参考方案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);
【讨论】:
以上是关于SQL按间隔分组,计数和求和的主要内容,如果未能解决你的问题,请参考以下文章