Potíž je v tom, že typ (small)datetime obsahuje mimo údaje data i čas. Můžeme samozřejmě zařídit, aby naše záznamy měly tento čas 00:00, ale stejně občas na tento problém narazíme.
Měli bychom rozlišit dvě situace, porovnávání s pevným dnem, nebo hledání shod ve variabilních datech.
Hledání shod ve variabilních datech
Jsme zde v situaci, kdy obě porovnávané složky jsou variabilní, u obou se musíme vypořádat s ignorováním složky dne.
SQL Server 2008 a novější verze mají datový typ date. Pokud tedy nejsme zrovna na nějaké pravěké verzi SQL, ukazuje se jako nejrychlejší (ač možná překvapivě) tato konverze:
SELECT MyColumn FROM MyTable
WHERE CONVERT(date, DateColumn1) = CONVERT(date, DateColumn2)
Pro starší verze SQL serveru je použitelných několik o dost méně výhodných (pomalejších) podob. Protože SQL 2005 a starší již dnes považuji za pravěk, nebudu již rozebírat jejich výhody/nevýhody a rychlost:
...
WHERE
(YEAR(Datum1) = YEAR(Datum2)
AND (MONTH(Datum1) = MONTH(Datum2)
AND (DAY(Datum1) = DAY(Datum2)
WHERE
(YEAR(Datum1) = YEAR(Datum2))
AND (DATEPART(dayofyear, Datum1) = DATEPART(dayofyear, Datum2))
WHERE CONVERT(varchar(10), Datum1, 101) = CONVERT(varchar(10), Datum2, 101)
WHERE FLOOR(CONVERT(float, Datum1)) = FLOOR(CONVERT(float, Datum2))
Porovnání s pevným dnem
Trochu jiná situace nastává v okamžiku, kdy jeden z údajů je pevný. Například hledáme záznamy založené určitého dne
DECLARE @DateFilter smalldatetime
SET @DateFilter = '20090305'
SELECT Created FROM MyTable
WHERE
(Created >= @DateFilter)
AND (Created < DATEADD(day, 1, @DateFilter))
…zde s výhodou celý problém převádíme na porovnávání s konstantami, a pokud máme k dispozici vhodný index, dokonce na operaci Index Seek.
Kupodivu úplně identický execution plan (Index Seek) a se stejnými časy dotazu (testováno na obrovských datech na MS SQL Serveru 2012) dostáváme i pro podobu:
DECLARE @DateFilter date
SET @DateFilter = '20090305'
SELECT Created FROM MyTable
WHERE CONVERT(date, Created) = @DateFilter
Líbí se mi to:
Líbí Načítání...