如何在相邻两个月的同一天使用group编写SQL语句对数据求和
我有这样一个数据表:如何在相邻两个月的同一天使用group编写SQL语句对数据求和,sql,sql-server,tsql,sql-server-2008-r2,Sql,Sql Server,Tsql,Sql Server 2008 R2,我有这样一个数据表: datetime data ----------------------- ... 2017/8/24 6.0 2017/8/25 5.0 ... 2017/9/24 6.0 2017/9/25 6.2 ... 2017/10/24 8.1 2017/10/25 8.2 datetime_range data_sum ----------------------------
datetime data
-----------------------
...
2017/8/24 6.0
2017/8/25 5.0
...
2017/9/24 6.0
2017/9/25 6.2
...
2017/10/24 8.1
2017/10/25 8.2
datetime_range data_sum
------------------------------------
...
2017/8/24~2017/9/24 100.9
2017/9/24~2017/10/24 120.2
...
我想写一条SQL语句,在一定的时间范围内,使用group在相邻两个月的第24个月对数据进行求和,例如:从2017/7/20到2017/10/25,如上所述
如何编写此SQL语句?我正在使用SQLServer2008R2
预期结果表如下所示:
datetime data
-----------------------
...
2017/8/24 6.0
2017/8/25 5.0
...
2017/9/24 6.0
2017/9/25 6.2
...
2017/10/24 8.1
2017/10/25 8.2
datetime_range data_sum
------------------------------------
...
2017/8/24~2017/9/24 100.9
2017/9/24~2017/10/24 120.2
...
一种概念上的方法是将一个月重新定义为每个正常月份的24日。使用SQL Server month函数,我们会将24日之后的任何日期指定为下一个月。然后我们可以按年份和这个月进行汇总,以获得数据的总和
WITH cte AS (
SELECT
data,
YEAR(datetime) AS year,
CASE WHEN DAY(datetime) > 24
THEN MONTH(datetime) + 1 ELSE MONTH(datetime) END AS month
FROM yourTable
)
SELECT
CONVERT(varchar(4), year) + '/' + CONVERT(varchar(2), month) +
'/25~' +
CONVERT(varchar(4), year) + '/' + CONVERT(varchar(2), (month + 1)) +
'/24' AS datetime_range,
SUM(data) AS data_sum
FROM cte
GROUP BY
year, month;
请注意,您建议的范围似乎包括两端的第24个,从会计角度来看,这是没有意义的。我假设该月包括并结束于24日,即25日是下一个会计期间的第一天
我认为最简单的方法是减去25天,然后按月累计:
select year(dateadd(day, -25, datetime)) as yr,
month(dateadd(day, -25, datetime)) as mon,
sum(data)
from t
group by dateadd(day, -25, datetime);
您可以格式化yr和mon以获取特定范围的日期,但这样做的话,聚合和yr/mon列可能就足够了。步骤0:构建日历表。每个数据库最终都需要一个日历表来简化这种计算 在此表中,您可能有以下列: 日期主键 白天 月 年 一刻钟 半年,例如1年或2年 第1至366年的第1天 星期几数字或文本 现在看来周末是多余的,但以后会节省很多时间 如果贵公司的会计年度未在1月1日开始,则为会计季度/年度 是假日吗 等 如果您的公司在24日开始其月份,则可以添加表示该月份的会计月份列 步骤1:在日历表上加入 步骤2:按日历表中的列分组 日历表一开始听起来很奇怪,但一旦你意识到它们实际上很小,即使它们跨越了几百年,它们很快就会成为一项重要资产
不要试图通过使用计算列来节省磁盘空间。您需要真正的列,因为它们速度更快,并且可以在必要时编制索引。老实说,即使是很宽的日历表,通常只有PK索引也足够了。我建议动态地构建一些日期范围行,这样您就可以将数据连接到这些行以进行聚合,例如:
+----+---------------------+---------------------+----------------+
| | period_start_dt | period_end_dt | your_data_here |
+----+---------------------+---------------------+----------------+
| 1 | 24.04.2017 00:00:00 | 24.05.2017 00:00:00 | 1 |
| 2 | 24.05.2017 00:00:00 | 24.06.2017 00:00:00 | 1 |
| 3 | 24.06.2017 00:00:00 | 24.07.2017 00:00:00 | 1 |
| 4 | 24.07.2017 00:00:00 | 24.08.2017 00:00:00 | 1 |
| 5 | 24.08.2017 00:00:00 | 24.09.2017 00:00:00 | 1 |
| 6 | 24.09.2017 00:00:00 | 24.10.2017 00:00:00 | 1 |
| 7 | 24.10.2017 00:00:00 | 24.11.2017 00:00:00 | 1 |
| 8 | 24.11.2017 00:00:00 | 24.12.2017 00:00:00 | 1 |
| 9 | 24.12.2017 00:00:00 | 24.01.2018 00:00:00 | 1 |
| 10 | 24.01.2018 00:00:00 | 24.02.2018 00:00:00 | 1 |
| 11 | 24.02.2018 00:00:00 | 24.03.2018 00:00:00 | 1 |
| 12 | 24.03.2018 00:00:00 | 24.04.2018 00:00:00 | 1 |
+----+---------------------+---------------------+----------------+
在连接到您的数据时,请不要试图使用中间值。按照上面的注释,使用您的data.date>=r.period\u start\u dt和data.date