Mam dwie tabele, w których kolumna [date]
jest typem DATETIME2(0)
.
Muszę porównać dwa rekordy tylko według części daty (dzień + miesiąc + rok), odrzucając części czasu (godziny + minuty + sekundy).
Jak mogę to zrobić?
Mam dwie tabele, w których kolumna [date]
jest typem DATETIME2(0)
.
Muszę porównać dwa rekordy tylko według części daty (dzień + miesiąc + rok), odrzucając części czasu (godziny + minuty + sekundy).
Jak mogę to zrobić?
Odpowiedzi:
Niewielką wadą odpowiedzi Marca jest to, że oba pola daty zostały umieszczone w typoszeregu, co oznacza, że nie będzie można wykorzystać żadnych indeksów.
Tak więc, jeśli istnieje potrzeba napisania zapytania, które może skorzystać z indeksu w polu daty, konieczne jest następujące (raczej zawiłe) podejście.
(DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
PS: Innym sposobem wyodrębnienia samej daty (w starszych wersjach SQL Server) jest użycie sztuczki polegającej na tym, jak data jest reprezentowana wewnętrznie.
CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)
Chociaż głosowałem za odpowiedzią oznaczoną jako poprawna. Chciałem poruszyć kilka rzeczy dla każdego, kto się na to natknie.
Ogólnie rzecz biorąc, jeśli filtrujesz wyłącznie według wartości daty . Firma Microsoft zaleca używanie neutralnego językowo formatu ymd
lub y-m-d
.
Należy zauważyć, że formularz „2007-02-12” jest uważany za neutralny językowo tylko w przypadku typów danych DATE, DATETIME2 i DATETIMEOFFSET.
Porównanie dat przy użyciu wyżej wymienionego podejścia jest proste. Rozważmy następujący, wymyślony przykład.
--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)
select
*
from
Sales.Orders
where
CONVERT(char(8), OrderDate, 112) = @filterDate
W idealnym świecie należy unikać wykonywania jakichkolwiek operacji na kolumnie filtrowanej, ponieważ może to uniemożliwić programowi SQL Server wydajne korzystanie z indeksów. To powiedziawszy, jeśli dane, które przechowujesz, dotyczą tylko daty, a nie godziny, rozważ przechowywanie DATETIME
o północy jako godzinie. Ponieważ:
Gdy SQL Server konwertuje literał na typ kolumny filtrowanej, przyjmuje północ, gdy część czasu nie jest wskazana. Jeśli chcesz, aby taki filtr zwracał wszystkie wiersze z określonej daty, musisz upewnić się, że wszystkie wartości są przechowywane z północą jako godziną.
Zatem zakładając, że interesuje Cię tylko data i przechowujesz swoje dane jako takie. Powyższe zapytanie można uprościć do:
--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)
select
*
from
Sales.Orders
where
OrderDate = @filterDate
Możesz spróbować tego
CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')
Testuję to dla MS SQL 2014, wykonując poniższy kod
select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
else '' end
Aby porównać dwie daty, takie jak MM / DD / RRRR do MM / DD / RRRR . Zapamiętaj Typ kolumny Field musi być typu dateTime. Przykład: columnName: PAYMENT_DATE dataType: DateTime .
potem możesz go łatwo porównać. Zapytanie to:
select * from demo_date where date >= '3/1/2015' and date <= '3/31/2015'.
To bardzo proste ...... Przetestowało to .....