Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of GETDATE() BETWEEN Two DateTime Fields where Both can be NULL

Is

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

Equivalent to:

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()) 

But with also catering for NULLs?

Or is there a more elegant way of doing it?

Where are parentheses needed here?

Thanks.

EDIT:

Both [DateOnline] AND [DateOffline] are of type DateTime

If [DateOnline] is NULL then the logic is "online now"

If [DateOffline] is NULL then the logic is "never go offline (once online)"

Sorry, I should have included this in my question to begin with.

like image 944
Chris Cannon Avatar asked Feb 21 '23 01:02

Chris Cannon


1 Answers

The author's second query will net better performance even if there is no indexes on those columns. If there are indexes, that's a no brainer... using coalesce will disable the index and do a table scan instead of index seek (very bad for performance).

Even if there aren't any indexes on those columns, "is null" will return a constant... whereas, in the case of coalesce function, the NULL values will still need to be evaluated each time. If you have a table full of NULL DateOnline and DateOffline, this performance leak cannot be ignored.

In any case, I can't think of a reason why you'd use coalesce in this case.

Also, I'm guessing (since you're checking date range) that those two dates are all or nothing. You probably only have to check for one of those dates.

 WHERE ([DateOnline] IS NULL)
 OR GETDATE() BETWEEN [DateOnline] AND [DateOffline]
like image 131
sam yi Avatar answered Feb 23 '23 13:02

sam yi