在一天的特定时间之后-哪种方法更好?

J. *_*ton 5 sql-server

我需要知道(并标记)子查询中的特定事件是否在下午3:30之后发生(无论日期如何)。
对于我的设置,我无法通过试用来确定哪种效率更高(它们返回得太快),并且执行计划没有帮助。

第二个(#2)在我看来似乎更有效率,因为文字只需要强制转换一次(每行只保留一个操作)。
但是,有时这样的操作在欺骗,因此我希望有人可以告诉我哪个更好。

CREATE TABLE #jccTestData([ProcessDate] datetime);
INSERT INTO #jccTestData ([ProcessDate])
VALUES 
    ('2019-03-12 10:23:28.000') ,('2019-03-17 11:22:40.000'), ('2019-03-18 11:25:30.000')
    ,('2019-03-19 11:42:02.000') ,('2019-03-11 12:45:30.000') ,('2019-03-12 13:14:20.000')
    ,('2019-03-13 15:20:13.000') ,('2019-03-14 15:29:40.000') ,('2019-03-15 15:29:59.997') 
    ,('2019-03-16 15:30:00.000') ,('2019-03-17 15:30:00.003') ,('2019-03-18 16:25:30.000')
    ,('2019-03-12 23:59:59.997') ,('2019-03-13 00:00:00.003') ,('2019-03-14 00:00:00.000')
    ,('2019-03-15 03:14:20.000') ,('2019-03-16 05:20:13.000')

SELECT 
    [ProcessDate]
    , Case When datepart(HH, [ProcessDate]) > 15
        OR (datepart(HH, [ProcessDate]) = 15 And datepart(n, [ProcessDate]) >= 30) 
        Then 'After 3:30 PM' 
        End As [After 3:30? #1]
    , Case When cast([ProcessDate] As time) >= cast('15:30:00' As time) 
        Then 'After 3:30 PM' 
        End As [After 3:30? #2]
FROM #jccTestData  
ORDER BY [ProcessDate]

DROP TABLE #jccTestData
Run Code Online (Sandbox Code Playgroud)

第二个似乎也更易于维护。

如果还有第三种选择,我也愿意接受。
SQL Server 2012以上版本

use*_*983 2

就个人而言,如果可以的话,我实际上会在您的表中添加一个计算列。如果使用该路由,数据类型绝对是可行的方法,但是如果您可以添加持久计算列,CONVERT那么您可以对该列建立索引,或者将其添加到现有列中,并在需要查询此列时维护 SARGability中的数据(我意识到这里的示例是一个临时表,但我怀疑真实的情况是):CASTtimeWHERE

ALTER TABLE #jccTestData ADD ProcessTime AS CONVERT(time,ProcessDate) PERSISTED;
Run Code Online (Sandbox Code Playgroud)

然后您可以查询该新列:

SELECT [ProcessDate],
       CASE WHEN ProcessTime >= '03:30' THEN 'After 3:30 PM' END AS [After 3:30?]
FROM #jccTestData
ORDER BY [ProcessDate];
Run Code Online (Sandbox Code Playgroud)

另外,避免对 中的列使用序数ORDER BY,最好使用列的实际名称。

旁注,您不需要有一列用于转换/转换为date数据类型。CONVERT(date,ProcessDate)并且CAST(ProcessDate AS date)都是 SARGable。