Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在相邻两个月的同一天使用group编写SQL语句对数据求和_Sql_Sql Server_Tsql_Sql Server 2008 R2 - Fatal编程技术网

如何在相邻两个月的同一天使用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对不起?我不明白。我想知道到目前为止,您在生成所需结果方面做了哪些尝试。如果有,你能在问题中发布代码吗?我想写一个sql来获得预期的结果表,如下所示,你是对的,我按照你说的做了。但我认为这些列是多余的,因为我可以随时将这些列添加到表中,并在真正需要时拆分datetime列以获取这些列的数据。是的,但是运行这些函数与仅查找数据相比,成本有多高?只有测试才能说明问题,但SQL Server中的标量函数出人意料地糟糕,常常会把并行运行查询的能力等问题搞砸。