4

SELECT [Id]
      ,[DateOnline] --Nullable
      ,[DateOffline] --Nullable
      ,[PageId]
      ,[DownloadId]
      ,[Weight]
  FROM [DownloadPage]
  WHERE GETDATE() BETWEEN [DateOnline] AND [DateOffline]

相当于:

SELECT [Id]
      ,[DateOnline] --Nullable
      ,[DateOffline] --Nullable
      ,[PageId]
      ,[DownloadId]
      ,[Weight]
  FROM [DownloadPage]
  WHERE ([DateOnline] IS NULL OR [DateOnline] <= GETDATE())
  AND ([DateOffline] IS NULL OR [DateOffline] > GETDATE()) 

但同时也满足 NULL 的需求?

还是有更优雅的方法?

这里哪里需要括号?

谢谢。

编辑:

[DateOnline] 和 [DateOffline] 都是 DateTime 类型

如果 [DateOnline] 为 NULL,则逻辑为“现在在线”

如果 [DateOffline] 为 NULL,则逻辑是“永不脱机(一旦联机)”

抱歉,我一开始就应该在我的问题中包含这个。

4

2 回答 2

5

即使这些列上没有索引,作者的第二个查询也会获得更好的性能。如果有索引,那就不用考虑了……使用 coalesce 将禁用索引并执行表扫描而不是索引查找(对性能非常不利)。

即使这些列上没有任何索引,“is null”也会返回一个常量......而在合并函数的情况下,仍然需要每次都评估 NULL 值。如果您有一个充满 NULL DateOnline 和 DateOffline 的表,则不能忽略此性能泄漏。

无论如何,我想不出你在这种情况下使用合并的原因。

另外,我猜测(因为您正在检查日期范围)这两个日期是全部或全部。您可能只需要检查其中一个日期。

 WHERE ([DateOnline] IS NULL)
 OR GETDATE() BETWEEN [DateOnline] AND [DateOffline]
于 2012-06-26T22:08:15.273 回答
3

您可以使用COALESCE将空值转换为有意义的值。在此示例中,我选择了始终在有效范围内的默认值。

WHERE GETDATE() BETWEEN COALESCE([DateOnline] , '1900-01-01')
                    AND COALESCE([DateOffline], '2099-12-31')

演示:http ://www.sqlfiddle.com/#!3/def09/1

于 2012-06-26T21:28:25.893 回答