如何使用带有where子句的select语句查询CTE

时间:2019-05-06 14:26:11

标签: sql sql-server sql-server-2008

我正在尝试在开始和结束日期的特定时间内返回所有事件,并将数据发送到我的应用程序。

服务器位于格林尼治标准时间(GMT),此应用程序的大多数用户位于EST,因此我使用dateadd进行了-4个小时的转换。

问题是,假设用户输入开始日期和结束日期为“ 03-23-2019”,查询将返回事件,日期和时间为“ 03-22-2019 9:00 PM”。 / p>

由于在select语句期间进行的时间转换,因此返回了日期范围之外的事件。

日期为'03 -22-2019 9:00 PM'的事件实际上在该数据库中为'03 -23-2019 1:00 AM'。

到目前为止,我已经尝试使用CTE运行执行转换的初始查询,然后尝试查询该CTE以提取符合条件的日期。

WITH incidents AS (
SELECT dv_u_store as LoginID, convert(varchar(30),dateadd(hh,-4,sys_created_on),22) as Submit_Date,
COALESCE(number,'') as Incident_Number, dv_incident_state as [Status], '' as  Product_Name, 
dv_priority as Priority, dv_short_description as [Summary]
From dbo.incident
WHERE dv_u_store IN ('004188') AND sys_created_on >= '04-23-2019' AND sys_created_on < DATEADD(DAY, 1, '04-26-2019')
)
SELECT *
FROM incidents
WHERE submit_date >= '04-23-2019' AND submit_date < DATEADD(DAY, 1, '04-26-2019')
ORDER BY submit_date DESC

开始日期:2019年4月23日

结束日期::2019年4月26日+ 1天(2019年4月27日)

因此在这种情况下,仅CTE就返回4行:

19年4月25日上午1:40

19年4月24日下午4:57

19年4月23日上午1:40

19/4/22下午8:18

然后我有另一个select语句,引用该CTE,该CTE具有WHERE子句,该子句再次传递开始和结束日期。

问题是,select语句不会过滤掉开始日期和结束日期范围之外的最后一个条目“ 04-22-19”。

如何查询具有开始日期和结束日期的CTE,以过滤掉经过4小时转换后不再符合条件的所有内容?

这样它只会返回:

19年4月25日上午1:40

19年4月24日下午4:57

19年4月23日上午1:40

我也愿意进行更好的时间转换。当事件返回我的应用程序时,我只需要将每个事件的时间保持在EST而不是GMT。

编辑

WITH incidents AS (
SELECT dv_u_store as LoginID, convert(VARCHAR(30), dateadd(hh,-4,sys_created_on), 22) as Submit_Date,
COALESCE(number,'') as Incident_Number, dv_incident_state as [Status], '' as  Product_Name, 
dv_priority as Priority, dv_short_description as [Summary]
From dbo.incident
WHERE dv_u_store IN ('004188') AND sys_created_on >= CAST('04-23-2019' AS datetime) AND sys_created_on < cast(DATEADD(DAY, 1, '04-26-2019') AS datetime)
)
SELECT *
FROM Incidents
WHERE submit_date >= cast('04-23-2019' AS datetime) AND submit_date < cast(DATEADD(DAY, 1, '04-26-2019') AS DATETIME)
ORDER BY submit_date DESC

正如评论所建议的,我改变了转换方式。现在,在where子句中,我将这些字符串转换为DATETIME。

1 个答案:

答案 0 :(得分:0)

试试看...

DECLARE
    @begdate DATETIME = '2019-04-23',
    @enddate DATETIME = '2019-04-26';

SELECT 
    @begdate = DATEADD(HOUR, -4, @begdate),
    @enddate = DATEADD(HOUR, 20, @enddate); -- rather than adding a day and adjusting for UTC, just add 20 hours...

SELECT
    LoginID = i.dv_u_store,
    Submit_Date = CONVERT(VARCHAR (30), DATEADD(hh, -4, i.sys_created_on), 22),
    Incident_Number = COALESCE(i.number, ''),
    Status = i.dv_incident_state,
    Product_Name = '',
    Priority = i.dv_priority,
    Summary = i.dv_short_description
FROM
    dbo.incident i
WHERE
    i.dv_u_store IN ('004188')
    AND i.sys_created_on >= @begdate
    AND i.sys_created_on < @enddate;