考虑到时区按月分组(SQL 服务器)
Group by month taking into account on timezone (SQL Server)
我看到了以下关于按月分组的问题:
DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0)
How to group by month from Date field using sql
这行得通 - 但我想 运行 针对特定时区执行此操作,同时考虑 DST。
具体来说,荷兰时区:欧洲中部标准时间 (GMT+1)。
这将是格林威治标准时间 + 2 有时带有夏令时。
在我的例子中,我有一个 Orders
table 和一个 OrderDatetime
,这是一个 DateTimeOffset(7)
。所有值均为 UTC (+00:00)。
SELECT
DATEADD(MONTH, DATEDIFF(MONTH, 0, [Orders].[OrderDateTime]), 0) AS [Month],
...
FROM
[Orders]
GROUP BY
DATEADD(MONTH, DATEDIFF(MONTH, 0, [Orders].[OrderDateTime]), 0)
考虑到特定时区时,这样的查询会是什么样子?
奖励:我最好将其设为可配置,这样时区将成为一个参数——这样的查询会是什么样子?
如果该值已经是 datetimeoffset
,那么 SQL 服务器已经考虑了时区,所以我怀疑您认为存在的问题并不存在。
取以下内容:
CREATE TABLE dbo.YourTable (YourColumn datetimeoffset(7));
INSERT INTO dbo.YourTable (YourColumn)
VALUES('2022-01-24T13:00:00+00:00'),
('2022-01-24T14:00:00+00:00'),
('2022-01-24T12:00:00+00:00');
GO
SELECT *
FROM dbo.YourTable
WHERE YourColumn = CONVERT(datetimeoffset(7),'2022-01-24T14:00:00+01:00');
GO
DROP TABLE dbo.YourTable;
GO
此returns值为2022-01-24T13:00:00.0000000 +00:00
的行,因为2022-01-24T13:00:00.0000000 +00:00
和2022-01-24T14:00:00+01:00
是同一时间。
对于 datetimeoffset
列,您可以在 SELECT 行
时使用 AT TIME ZONE
关键字
[编辑]:添加了已声明的变量以使 TZ 可配置
drop table if exists #YourTable;
go
CREATE TABLE #YourTable(
YourColumn datetimeoffset(7));
insert #YourTable (YourColumn) VALUES
('2022-01-24T13:00:00+00:00'),
('2022-01-24T14:00:00+00:00'),
('2022-01-24T12:00:00+00:00');
declare @MyTZ sysname=N'Central European Standard Time';
select *, YourColumn at time zone @MyTZ conv_tz
from #YourTable;
YourColumn conv_tz
2022-01-24 13:00:00.0000000 +00:00 2022-01-24 14:00:00.0000000 +01:00
2022-01-24 14:00:00.0000000 +00:00 2022-01-24 15:00:00.0000000 +01:00
2022-01-24 12:00:00.0000000 +00:00 2022-01-24 13:00:00.0000000 +01:00
在您的公式中使用如下:
DATEADD(MONTH, DATEDIFF(MONTH, 0, YourColumn at time zone @MyTZ), 0) YourColTZ
您可以使用SWITCHOFFSET
CREATE TABLE test
(
OrderDateTime datetimeoffset
, tz varchar (8)
);
INSERT INTO test
VALUES ('2022-01-31 17:00:00 -5:00', '+08:00');
SELECT
DATEADD(MONTH, DATEDIFF(MONTH, 0, [OrderDateTime]), 0) AS [Month1]
, DATEADD(MONTH, DATEDIFF(MONTH, 0, SWITCHOFFSET (OrderDateTime, tz)), 0) AS [Month2]
FROM test;
Returns
Month1 Month2
2022-01-01 00:00:00.000 2022-02-01 00:00:00.000
我看到了以下关于按月分组的问题:
DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0)
How to group by month from Date field using sql
这行得通 - 但我想 运行 针对特定时区执行此操作,同时考虑 DST。
具体来说,荷兰时区:欧洲中部标准时间 (GMT+1)。
这将是格林威治标准时间 + 2 有时带有夏令时。
在我的例子中,我有一个 Orders
table 和一个 OrderDatetime
,这是一个 DateTimeOffset(7)
。所有值均为 UTC (+00:00)。
SELECT
DATEADD(MONTH, DATEDIFF(MONTH, 0, [Orders].[OrderDateTime]), 0) AS [Month],
...
FROM
[Orders]
GROUP BY
DATEADD(MONTH, DATEDIFF(MONTH, 0, [Orders].[OrderDateTime]), 0)
考虑到特定时区时,这样的查询会是什么样子?
奖励:我最好将其设为可配置,这样时区将成为一个参数——这样的查询会是什么样子?
如果该值已经是 datetimeoffset
,那么 SQL 服务器已经考虑了时区,所以我怀疑您认为存在的问题并不存在。
取以下内容:
CREATE TABLE dbo.YourTable (YourColumn datetimeoffset(7));
INSERT INTO dbo.YourTable (YourColumn)
VALUES('2022-01-24T13:00:00+00:00'),
('2022-01-24T14:00:00+00:00'),
('2022-01-24T12:00:00+00:00');
GO
SELECT *
FROM dbo.YourTable
WHERE YourColumn = CONVERT(datetimeoffset(7),'2022-01-24T14:00:00+01:00');
GO
DROP TABLE dbo.YourTable;
GO
此returns值为2022-01-24T13:00:00.0000000 +00:00
的行,因为2022-01-24T13:00:00.0000000 +00:00
和2022-01-24T14:00:00+01:00
是同一时间。
对于 datetimeoffset
列,您可以在 SELECT 行
AT TIME ZONE
关键字
[编辑]:添加了已声明的变量以使 TZ 可配置
drop table if exists #YourTable;
go
CREATE TABLE #YourTable(
YourColumn datetimeoffset(7));
insert #YourTable (YourColumn) VALUES
('2022-01-24T13:00:00+00:00'),
('2022-01-24T14:00:00+00:00'),
('2022-01-24T12:00:00+00:00');
declare @MyTZ sysname=N'Central European Standard Time';
select *, YourColumn at time zone @MyTZ conv_tz
from #YourTable;
YourColumn conv_tz
2022-01-24 13:00:00.0000000 +00:00 2022-01-24 14:00:00.0000000 +01:00
2022-01-24 14:00:00.0000000 +00:00 2022-01-24 15:00:00.0000000 +01:00
2022-01-24 12:00:00.0000000 +00:00 2022-01-24 13:00:00.0000000 +01:00
在您的公式中使用如下:
DATEADD(MONTH, DATEDIFF(MONTH, 0, YourColumn at time zone @MyTZ), 0) YourColTZ
您可以使用SWITCHOFFSET
CREATE TABLE test
(
OrderDateTime datetimeoffset
, tz varchar (8)
);
INSERT INTO test
VALUES ('2022-01-31 17:00:00 -5:00', '+08:00');
SELECT
DATEADD(MONTH, DATEDIFF(MONTH, 0, [OrderDateTime]), 0) AS [Month1]
, DATEADD(MONTH, DATEDIFF(MONTH, 0, SWITCHOFFSET (OrderDateTime, tz)), 0) AS [Month2]
FROM test;
Returns
Month1 Month2
2022-01-01 00:00:00.000 2022-02-01 00:00:00.000