SQL 声明帮助:select 产品可交易至特定时间

SQL statement help : select products tradable till specific time

假设我有一个 table 存储订单 ID 和相应的产品 - 像这样:

Product ID | Order ID (PK) | Order Placement Date
Apple      | 2455          | 2022-04-18 13:55:50.100
Apple      | 2456          | 2022-04-18 15:50:40.100
Appel      | 3457          | 2022-04-18 17:59:10.100
Appel      | 3458          | 2022-04-18 18:40:10.100
Appel      | 3459          | 2022-04-19 09:30:50.100
Appel      | 3459          | 2022-04-19 14:20:20.100

我怎样才能每天获取从昨天 18:00 CET 到那天 18:00 CET 之前的任何时间点的所有可交易产品(已下订单)。那么当日CET后18:00后可交易的新品种,首次下单,必须纳入次日select数据?

此外 Order Placement Date 将是 DateTime - UTC 时区,我正在使用 SQL Server 2019。

类似

SELECT DISTINCT Product ID, Order ID, Order Placement Date
FROM TableName
Where Order Placement Date --> From yesterday 18h until today 18:00 CET

Select 2022-04-18 时的结果样本:

Product ID | Order ID (PK) | Order Placement Date
Apple      | 2455          | 2022-04-18 13:55:50.100
Apple      | 2456          | 2022-04-18 15:50:40.100
Appel      | 3457          | 2022-04-18 17:59:10.100

Select 2022-04-19 时的结果样本:

Product ID | Order ID (PK) | Order Placement Date
Appel      | 3458          | 2022-04-18 18:40:10.100
Appel      | 3459          | 2022-04-19 09:30:50.100
Appel      | 3459          | 2022-04-19 14:20:20.100

这有点乱,但应该可以。我怀疑可能有一种不那么丑陋的方法,但是哦。但是,我假设您使用的是最新版本的 SQL 服务器,它支持 AT TIME ZONE.

首先我们得到当前日期;我假设“今天”是从服务器的角度来看的。然后我们 CONVERTdate (删除时间)然后返回到 datetime2,所以我们可以使用 AT TIME ZONE,我们声明它是中欧。 SQL 自动处理 DST 的服务器,它会假定 datetime2 值对于时区是正确的。然后我们将该时间更改为 UTC 并将 CONVERT 更改回 datetime,以便该列上没有隐式转换。然后我们对上边界做同样的事情,但增加了 8 小时:

CREATE TABLE dbo.YourTable (ProductID int,
                            OrderID int,
                            OrderPlacementDate datetime); --Per question, this is UTC

INSERT INTO dbo.YourTable (ProductID,
                           OrderID,
                           OrderPlacementDate)
VALUES(2,2,'20220418 21:48:59.123'), --Would be 2022-04-18 23:48:59.123 CEST
      (1,1,'20220418 22:15:17.167'), --Would be 2022-04-19 00:15:17.167 CEST
      (1,1,'20220419 15:15:17.167'), --Would be 2022-04-19 17:15:17.167 CEST
      (1,1,'20220419 16:15:17.167'); --Would be 2022-04-19 18:15:17.167 CEST
GO


SELECT *
FROM dbo.YourTable
WHERE OrderPlacementDate >= CONVERT(datetime,(CONVERT(datetime2(3),CONVERT(date,GETDATE())) AT TIME ZONE 'Central Europe Standard Time') AT TIME ZONE 'UTC')
  AND OrderPlacementDate <= CONVERT(datetime,DATEADD(HOUR,18,CONVERT(datetime2(3),CONVERT(date,GETDATE())) AT TIME ZONE 'Central Europe Standard Time' AT TIME ZONE 'UTC'))
GO

DROP TABLE dbo.YourTable

db<>fiddle

怎么样:

SELECT *
FROM TableName
WHERE [Order Placement Date] < DATETIMEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()),DAY(GETDATE()),18,0,0,0)
AND [Order Placement Date] >= DATETIMEFROMPARTS(YEAR(DATEADD(day, -1, GETDATE())),MONTH(DATEADD(day, -1, GETDATE())),DAY(DATEADD(day, -1, GETDATE())),18,0,0,0)