【问题标题】:Return result between Declared dates, possible optimization声明日期之间的返回结果,可能的优化
【发布时间】:2020-12-26 18:08:16
【问题描述】:

这里检查 2 列以按日期时间使用搜索查询(A 和 B 情况)。 在列中使用声明的日期进行搜索过滤器:

A) Entry_Timestamp,它正在按预期工作,但我认为带有 BETWEEN 的底部看起来很难看。有什么方法可以缩短或优化代码?请举例说明。

B) Received_Timestamp,这里失败了

注意Entry_Timestamp 数据的类型是 datetime,但列 Received_Timestampdatetime2(2)

A) 代码:

DECLARE @DateBeg DATETIME = '2018-12-01T04:00:00'
DECLARE @DateEnd DATETIME = '2018-12-01T05:59:59'

SELECT   
    dd.SN AS ID, 
    DATEADD(mi, dat.UtcOffset, DATEADD(ss, dat.ValueTime, '1970-01-01T00:00:00')) AS Entry_Timestamp,
    DATEADD(mi, dat.UtcOffset, dat.ReceivedTime) AS Received_Timestamp,
    val.Value
FROM    
    DataStore.AgregatedStorageData dat
CROSS APPLY 
    DataStore.fn_ConvertValueData(dat.ValueData, dat.ValueUnit, dat.ValueScaler) val
INNER JOIN 
    DataStore.dc_CaptureObjects co ON co.CaptureObjectID = dat.CaptureObjectID
                                   AND co.ClassId = 3
                                   AND co.LogicalName IN (0x0100011D00FF -- ActiveFilter
                                                         )
INNER JOIN 
    dbo.dm_Devices dd ON dat.DeviceId = dd.Id
WHERE   
    dat.ValueTime BETWEEN DATEDIFF(ss, '1970-01-01T00:00:00', @DateBeg - '02:00:00') AND 
                          DATEDIFF(ss, '1970-01-01T00:00:00', @DateEnd - '02:00:00')

结果:

B) 代码:

DECLARE @DateBeg DATETIME2 = '2018-12-01T04:00:00'
DECLARE @DateEnd DATETIME2 = '2018-12-01T05:59:59'

SELECT
    dd.SN AS ID,
    DATEADD(mi, dat.UtcOffset, DATEADD(ss, dat.ValueTime, '1970-01-01T00:00:00')) AS Entry_Timestamp,
    DATEADD(mi, dat.UtcOffset, DATEADD(ss, dat.ReceivedTime, '1970-01-01T00:00:00')) AS Received_Timestamp,
    val.Value
FROM    
    DataStore.AgregatedStorageData dat
CROSS APPLY 
    DataStore.fn_ConvertValueData(dat.ValueData, dat.ValueUnit, dat.ValueScaler) val
INNER JOIN 
    DataStore.dc_CaptureObjects co ON co.CaptureObjectID = dat.CaptureObjectID
                                   AND co.ClassId = 3
                                   AND co.LogicalName IN (0x0100011D00FF -- ActiveFilter
                                                         )
INNER JOIN 
    dbo.dm_Devices dd ON dat.DeviceId = dd.Id
WHERE   
    dat.ReceivedTime BETWEEN DATEDIFF(ss, '1970-01-01T00:00:00', @DateBeg - '02:00:00')
                         AND DATEDIFF(ss, '1970-01-01T00:00:00', @DateEnd - '02:00:00')

我收到一个错误

操作数数据类型 datetime2 对减法运算符无效。第21行

【问题讨论】:

  • 样本数据、期望的结果以及对您想要完成的目标的清晰解释都会有所帮助。
  • @GordonLinoff 只是提出问题。您从描述中想到的仍然缺失。 A) 点提供了工作搜索查询和图片中的结果。询问可能的查询优化; B)在其他列(datetime2)中搜索查询,期望的结果是从开始到完成没有错误,然后类似于点A)图片中的内容。刚刚切换了搜索发生的列。
  • “看起来很丑”?几乎无法衡量 T-SQL...美丽在旁观者的眼中...它的工作是否更相关。

标签: sql sql-server


【解决方案1】:

错误原因

操作数数据类型 datetime2 对减法运算符无效。第21行

问题是当您从 BETWEEN 子句的“@DateBeg”和“@DateEnd”中减去 2 小时时。

你可以试试

WHERE   
dat.ReceivedTime BETWEEN DATEDIFF(ss, '1970-01-01T00:00:00', DATEADD(Hour,-2,@DateBeg) )
                     AND DATEDIFF(ss, '1970-01-01T00:00:00', DATEADD(Hour,-2,@DateEnd) )

【讨论】:

  • 问题是你不能在 datetime2 中使用减法。另一种方法是转换为日期时间。
  • 我确实尝试了 B),现在在第 5 行:操作数类型冲突:datetime2 与 int 不兼容。
猜你喜欢
  • 1970-01-01
  • 2020-02-28
  • 1970-01-01
  • 2011-09-27
  • 2011-07-18
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多