上个月全年数据输出

Output of data from the entire last month

提问人:Razzaf 提问时间:7/20/2023 最后编辑:Razzaf 更新时间:8/2/2023 访问量:82

问:

简要解释一下我的问题:

我们公司使用库存工具,它应该在每个月初(即 1 号)自动输出上个月的所有库存变动。在这里,我可以通过日期过滤器来控制应该输出表的哪些数据。目前我的过滤器如下:“> CURRENT_TIMESTAMP - 31”。因此,将显示过去 31 天到今天的所有库存变动。然而,不幸的是,这只有 95% 正确,因为例如,如果我有一个月只有 30 天,或者像 2 月份一样只有 28 天,我总是把前一个月的最后几天也拿走。现在来回答我的问题。

是否可以设置过滤器或SQL语句,该语句将始终仅向我输出该月比当前月份早一个月的库存变动?例如,输出发生在 2023 年 8 月 1 日,然后我想获取上个月的所有库存变动,因此 7 月(2023 年 7 月 1 日 - 2023 年 7 月 31 日输出。

不幸的是,我是SQL的新手,所以我很难找到解决方案。

sql-server 日期时间

评论

1赞 JNevill 7/20/2023
完全有可能,但是在每个RDBMS中编写逻辑的方式是不同的。您能分享一下您正在使用的 RDBMS(Sql Server、mysql、oracle、postgres 等)吗?
1赞 Reporter 7/20/2023
meta.stackoverflow.com/questions/388759/......
1赞 Jonas Metzler 7/20/2023
例如,在 SQL Server DB 中,将使用 MONTH。MONTH(GETDATE()) 将返回 7。这样的函数存在于每个RDBMS中,具有相似的名称和功能。
0赞 Arvo 7/20/2023
在 SQL Server 中,我只使用 .datediff(month, ...)
0赞 Adrian Maxwell 7/21/2023
添加标识您实际使用的数据库的标签。

答:

1赞 Adrian Maxwell 7/21/2023 #1

在 SQL Server 中,current_timestamp返回一个值,例如 2023-07-22 07:53:41.270。此函数是等效于 特定于 SQL Server 的 GETDATE() 函数。datetime

从 current_timestamp 或 getdate() 确定“上个月”开头的方法如下:

  1. 根据已知基准面计算月份(此处我们使用零)DATEDIFF(MONTH, 0, GETDATE())
  2. 将该月数相加为零,然后扣除 1 个月DATEADD(MONTH, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
  3. 将当前月份第一天的相同月数添加到零:DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)

因此,我们现在可以过滤“>= 上个月第 1 天”和“本月第 1 天”<数据,例如:

-- T-SQL (SQL Server)
SELECT *
FROM your_table
WHERE timestamp_column >= DATEADD(MONTH, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
  AND timestamp_column < DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0);

无论所用列的日期/时间精度如何,此 where 子句都将动态过滤上个月内的任何数据,即它将适用于 date、smalldatetime、datetime 和 datetime2

注意:如果您愿意,可以使用代替,但我相信您会发现有关类似需求的大多数信息仍然使用 SQL Server 特定的 getdate() 函数 - 所以我也效仿了。current_timestampgetdate()

若要进一步了解此日期操作,请尝试以下查询:

select 
  current_timestamp "current timestamp"
, getdate()         "getdate"
, DATEDIFF(MONTH, 0, GETDATE()) "months from zero"
, DATEADD(MONTH, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)) "day 1 last month"
, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0) "day 1 this month"
当前时间戳 获取日期 从零开始的月份 上个月的第 1 天 本月第一天
2023-07-22 01:07:00.753 2023-07-22 01:07:00.753 1482 2023-06-01 00:00:00.000 2023-07-01 00:00:00.000

小提琴

一锤定音。在筛选日期范围(如“上个月”)时,不要试图使用“之间”。SQL 中“between”的问题在于它包括范围的起点和终点 - 这可能会导致对边界上的任何数据进行双重计算。如前所述,使用 with 的组合要安全得多。>=<

评论

0赞 Razzaf 7/21/2023
首先,感谢您的解释。我会尝试这些陈述。但我还有一个问题。什么是DATE_TRUNC?或者更确切地说,我应该/必须放在那里的价值是什么?
0赞 Adrian Maxwell 7/21/2023
确定您需要解决的数据库。是Postgres吗?Date_truc只是将时间从时间戳中剪切,例如 2023-07-21 09:23:57 变为 2023-07-21 00:00:00
0赞 Adrian Maxwell 7/21/2023
再看一遍:如果你用current_date而不是current_timestamp你就不需要date_trunc。
0赞 Razzaf 7/21/2023
它是mssql。我希望这会有所帮助。我已将其添加为标签。
1赞 Razzaf 8/1/2023
感谢您的帮助。你上面的SQL语句帮助了我。在我稍微修改了一下之后,它符合我的要求。