I have a list of records with datetimes over more than 1 year. My goal is to compare the count of today's records with the count of records from last year, where the week # and day of the week from last year's search match today's week # and day of the week.
For example: if today is 07-26-2016, then the week number is 31, and the day is Tuesday (3). Then I would be searching for week number 31, Tuesday (3) of 2015. This day is 07-28-2015.
My problem is that, if I use a WHERE clause with the date in form '07-28-2015', the query completes in ~30 seconds. But if I use a WHERE clause with DATEPARTs for year, week, and day of week, my query takes > 10 minutes.
Here are the two queries to compare:
first, with the full date in the WHERE clause. This takes 30 seconds
SELECT COUNT(*)
FROM my_table
WHERE CAST(my_datetime AS DATE) = '2015-07-28'
now, with the DATEPARTs. This takes 10+ minutes
SELECT COUNT(*)
FROM my_table
WHERE DATEPART(yy,CAST(my_datetime AS DATE)) = 2015
AND DATEPART(wk,CAST(my_datetime AS DATE)) = 31
AND DATEPART(dw,CAST(my_datetime AS DATE)) = 3
I have also tried the second query without casting my_datetime as DATE, and it is just as slow. They DO work, and I have compared the results from the two, but it is necessary that I use the second query so that I can replace the static values (2015, 31, 3) with
DATEPART(yy,GETDATE())-1 / DATEPART(yy,CAST(GETDATE() AS DATE))-1
DATEPART(wk,GETDATE()) / DATEPART(wk,CAST(GETDATE() AS DATE))
DATEPART(dw,GETDATE()) / DATEPART(dw,CAST(GETDATE() AS DATE))
That way, the query will always give me results for last year's corresponding date.
How do I optimize this query to be faster? Or am I approaching this incorrectly?
Best Answer
I like Kenneth Fisher's response.
If you don't have the option of creating the calendar table, I think you should looks for the exact date first, set that date as a variable, then use the variable in your WHERE clause.
Building the date takes less than a second, then you have a direct filter.
Took a little while to get the calculations right, but I think this works.
Today's date "match" for last year returns: 7/28/2015.