Převést datetime pole SQL serveru porovnat pouze data součásti, s indexovaných vyhledáváními

hlasů
28

Byl jsem dělat convert(varchar,datefield,112)na každé pole datum, které jsem za použití v ‚mezi‘ dotazů v SQL serveru, aby zajistily, že jsem účetnictví pouze pro data a nechybí některý založený na časové části datetime polí.

Teď jsem slyšel, že konvertité nejsou polohovatelná a že existují lepší metody, v SQL Server 2005, porovnat data část datetimes v dotazu zjistit, zda data spadají v řadě.

Jaký je optimální, polohovatelné, způsob něco takového:

select * from appointments
where appointmentDate>='08-01-2008' and appointmentDate<'08-15-2008'
Položena 09/12/2008 v 15:59
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
65

Nejlepším způsobem, jak zbavit časovou část pole datetime používá DateDiff a DateAdd funkce.

   DateAdd(day, datediff(day,0, MydateValue), 0)

To trvá advantedge skutečnost, že ukládá SQL Server termínech dvou celých čísel, jedno číslo představuje počet dnů od prvního dne „0“ - (01.1.1900), a druhý, který představuje počet klíšťat (každé klíště je asi 3,33 ms ) od půlnoci (po dobu) *.

výše uvedený vzorec prostě musí jen pro čtení na celé. Neexistuje žádná konverze nebo zpracování, které musí, tak to je velmi rychlý.

Chcete-li, aby vaše dotazy použít index ... použít tento vzorec na vstupu první filtrační parametry, nebo na „druhé“ straně znaménko rovná se z časového pole datum tabulky, takže optimalizátor dotazu nemusí spustit výpočet na každém datetime pole v tabulce určit, které řádky splňují predikát filtru. Tím se hledaný argument "SARG-able" (Search argument)

Where MyDateTimeColumn > DateAdd(day, 
      datediff(day,0, @MydateParameter), 0)    -- SARG-able

spíše než

Where DateAdd(day, datediff(day,0, 
      MyDateTimeColumn ), 0) > @MydateParameter -- Not SARG-able

* POZNÁMKA. Interně, druhá celé číslo (čas část) ukládá klíšťata. V den jsou 24 x 60 x 60 x 300 = 25,920,000 klíšťata (náhodně právě pod maximální hodnoty 32 bitové celé číslo se vejde). Nicméně, nemusíte se starat o to, když aritmeticky modifikaci datetime ... Při přidávání nebo odečtením hodnoty z datetimes můžete považovat hodnotu jako zlomek, jako by to bylo přesně roven frakční část dne, jako kdyby kompletní datetime hodnota byla reálné číslo, skládající se z celé číslo části představující datum a zlomkovou část reprezentující čas). tj,

`Declare @Dt DateTime  Set @Dt = getdate()  
 Set @Dt = @Dt + 1.0/24  -- Adds one hour  
 Select @Dt  
 Set @Dt = @Dt - .25 -- Moves back 6 hours  
 Select @Dt`
Odpovězeno 09/12/2008 v 16:07
zdroj uživatelem

hlasů
5

Konverzi číselných typů na řetězec hodnoty (typ boxu) není nejvýkonnější způsob, jak dělat to, co jste hledali. Není to opravdu o index-schopný, protože skutečný typ sloupce je datum čas.

Pokud hledáte nejlepší způsob, jak dotaz pro data, pak váš příklad je v pořádku, ale možná budete chtít vzít v úvahu rozdíl 3 ms přesnost MSSQL. To může znamenat, že záznamy z jednoho dne může ukázat až v další den výsledku.

Tento

select * from appointments where appointmentDate>='08-01-2008' and appointmentDate<'08-15-2008'

By měl být tento

select * from appointments where appointmentDate>='08-01-2008' and appointmentDate<='08-14-2008 23:59:59.996'
Odpovězeno 09/12/2008 v 16:11
zdroj uživatelem

hlasů
2

Je to správné - dělá konverze bude provádět konverzi pro každou řadu dotazovaný. Je lepší nechat sloupce datum jako data, a předat ve svých WHERE jsou termíny:

select * from appointments where appointmentdate between 
'08/01/2008' AND '08/16/2008'

Poznámka: Ponechání mimo čas znamená půlnoc (00: 00.000), takže bude zahrnovat všechny časy 08/01 a všechny časy z 08/15, a vše, co je přesně 08/16/2008 00:00:00

Odpovězeno 09/12/2008 v 16:06
zdroj uživatelem

hlasů
1

Mají vypočítaný přetrvávaly sloupec vypočítat výraz, který potřebujete. Jsou-li sloupce počítány a přetrvávaly, oni mohou také být indexovány.

Odpovězeno 09/12/2008 v 16:10
zdroj uživatelem

hlasů
0

K dispozici je také způsob, jak je popsáno v http://www.stillnetstudios.com/comparing-dates-without-times-in-sql-server/

SELECT CAST(FLOOR(CAST( getdate() AS float )) AS datetime)
Odpovězeno 28/09/2011 v 13:31
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more