Jak mogę obciąć datetime w SQL Server?

Jaki jest najlepszy sposób na obcięcie wartości datetime (aby usunąć godziny minut i sekund) w SQL Server 2008?

Na przykład:

declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)

-----------------------
2009-05-28 00:00:00.000
Author: Jason Plank, 2009-05-29

13 answers

To nadal często zbiera dodatkowe głosy, nawet kilka lat później, więc muszę go zaktualizować dla nowoczesnych wersji SQL Server. Dla Sql Server 2008 i nowszych jest to proste:

cast(getDate() As Date)

Zauważ, że ostatnie trzy akapity na dole nadal mają zastosowanie, i często musisz zrobić krok w tył i znaleźć sposób, aby uniknąć obsady w pierwszej kolejności.

Ale są inne sposoby, aby to osiągnąć. Oto najczęstsze.

The correct way (new since Sql Server 2008):

cast(getdate() As Date)

The correct way (old):

dateadd(dd, datediff(dd,0, getDate()), 0)

To jest już starsze, ale nadal warto o tym wiedzieć, ponieważ może również łatwo dostosować się do innych punktów czasowych, takich jak pierwsza chwila miesiąca, minuty, godziny lub roku.

Ten poprawny sposób wykorzystuje udokumentowane funkcje, które są częścią standardu ansi i mają gwarancję działania, ale mogą być nieco wolniejsze. Działa poprzez ustalenie, ile dni jest od dnia 0 do dnia bieżącego i dodanie, że wiele dni wstecz do dnia 0. Będzie działać bez względu na sposób przechowywania datetime i bez względu na ustawienia regionalne.

Szybki sposób:

cast(floor(cast(getdate() as float)) as datetime)

To działa, ponieważ kolumny datetime są przechowywane jako 8-bajtowe wartości binarne. Rzucaj je do float, podnoś je, aby usunąć ułamek, a część czasowa wartości zniknie po oddaniu ich z powrotem do datetime. To wszystko jest po prostu trochę przesunięcie bez skomplikowanej logiki i to jest Bardzo szybko.

Należy pamiętać, że polega to na szczegóły wdrożenia Microsoft może dowolnie zmieniać w dowolnym momencie, nawet w automatycznej aktualizacji usługi. Nie jest też zbyt przenośny. W praktyce jest bardzo mało prawdopodobne, że ta implementacja zmieni się w najbliższym czasie, ale nadal ważne jest, aby być świadomym niebezpieczeństwa, jeśli zdecydujesz się go użyć. A teraz, gdy mamy możliwość obsady jako randki, rzadko jest to konieczne.

Zła droga:

cast(convert(char(11), getdate(), 113) as datetime)

Niewłaściwy sposób działa poprzez konwersję na łańcuch, obcinanie łańcucha i konwersję wracamy do datetime. To jest źle, z dwóch powodów: 1) może nie działać we wszystkich lokalizacjach i 2) chodzi o najwolniejszy możliwy sposób, aby to zrobić... i to nie tylko trochę; to jak rząd wielkości lub dwa wolniejsze niż inne opcje.


Update to zostało coraz kilka głosów ostatnio, a więc chcę dodać do niego, że od czasu opublikowania tego widziałem dość solidne dowody, że SQL Server zoptymalizuje od różnicy wydajności między " poprawne" sposób i "szybki" sposób, co oznacza, że powinieneś teraz faworyzować tę pierwszą.

W obu przypadkach, chcesz pisać swoje zapytania, aby uniknąć konieczności tego w pierwszej kolejności . To bardzo rzadkie, że należy wykonać tę pracę na bazie danych.

W większości miejsc baza danych jest już twoim wąskim gardłem. Generalnie to serwer jest najdroższy w dodaniu sprzętu do poprawy wydajności i najtrudniejszy do poprawienia tych dodatków (trzeba balansować dyski z pamięci, np.). Jest to również najtrudniejsze do skalowania na zewnątrz, zarówno technicznie, jak i z biznesowego punktu widzenia; znacznie łatwiej jest technicznie dodać serwer WWW lub aplikacji niż serwer bazy danych, a nawet jeśli byłoby to fałszywe, nie płacisz 20,000 + za licencję serwera dla IIS lub apache.

Chodzi o to, że w miarę możliwości powinieneś wykonać tę pracę na poziomie aplikacji. tylko Czas, w którym powinieneś kiedykolwiek znaleźć się obcinając datetime na serwerze Sql jest wtedy, gdy musisz grupować według dnia, a nawet wtedy powinieneś prawdopodobnie mieć dodatkową kolumnę ustawioną jako kolumnę obliczoną, utrzymywaną w czasie wstawiania/aktualizacji lub utrzymywaną w logice aplikacji. Pozbądź się tej łamającej indeks, obciążającej procesor bazy danych.

 428
Author: Joel Coehoorn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-13 18:32:01

Tylko dla SQL Server 2008

CAST(@SomeDateTime AS Date) 

Następnie wrzuć go z powrotem do datetime, jeśli chcesz

CAST(CAST(@SomeDateTime AS Date) As datetime)
 43
Author: DJ.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-28 22:15:46

Aby uzyskać bardziej kompletną odpowiedź, oto sposób na skrócenie dowolnej części daty i włącznie z minutami(zastąp GETDATE() datą do skrócenia).

Różni się to od przyjętej odpowiedzi tym, że możesz użyć nie tylko dd (dni), ale dowolnej części daty (patrz tutaj):

dateadd(minute, datediff(minute, 0, GETDATE()), 0)

Zauważ, że w powyższym wyrażeniu 0 jest stałą datą na początku roku (1900-01-01). Jeśli trzeba obciąć na mniejsze części, takie jeśli chodzi o sekundy lub milisekundy, musisz wziąć stałą datę, która jest bliższa dacie, która ma być obcięta, aby uniknąć przepełnienia.

 19
Author: Lucero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-31 12:02:27

Fragment, który znalazłem w sieci, kiedy musiałem to zrobić, brzmiał:

 dateadd(dd,0, datediff(dd,0, YOURDATE))
 e.g.
 dateadd(dd,0, datediff(dd,0, getDate()))
 7
Author: Tom Ritter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-28 21:30:17

W SQl 2005 twoja funkcja trunc_date może być napisana w ten sposób.

(1)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
    CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END
Pierwsza metoda jest dużo czystsza. Używa tylko 3 wywołań metod, w tym final CAST () i nie wykonuje konkatenacji string, co jest automatycznym plusem. Ponadto nie ma tu wielkich odlewów typowych. Jeśli możesz sobie wyobrazić, że znaczniki daty/czasu mogą być reprezentowane, konwersja z dat na Liczby i z powrotem na Daty jest dość łatwym procesem.

(2)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
      SELECT CONVERT(varchar, @date,112)
END

Jeśli są zaniepokojeni implementacją datetimes (2) lub (3) przez microsoft może być ok.

(3)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CAST((STR( YEAR( @date ) ) + '/' +STR( MONTH( @date ) ) + '/' +STR( DAY(@date ) )
) AS DATETIME
END

Po Trzecie, bardziej wyrazista metoda. Wymaga to podziału daty Na części Rok, Miesiąc i dzień, ułożenia ich razem w formacie "RRRR/MM/dd", a następnie przeniesienia jej z powrotem na datę. Metoda ta obejmuje 7 wywołań metod, w tym final CAST (), nie wspominając o konkatenacji łańcuchów.

 1
Author: AlejandroR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-25 04:14:47
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)
 1
Author: Dean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-10 14:36:01

Select cast(floor(Cast(getdate() as float)) as datetime) Odniesienie do tego: http://microsoftmiles.blogspot.com/2006/11/remove-time-from-datetime-in-sql-server.html

 0
Author: Sudhir Bastakoti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-27 12:34:28

Dla tych z Was, którzy szukali sposobu na skrócenie pola DATETIME do czegoś mniej niż cały dzień, na przykład co minutę, możecie użyć tego:

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) + (FLOOR((CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))) * 1440.0) + (3.0/86400000.0)) / 1440.0 AS DATETIME)

Więc gdyby dzisiaj było 2010-11-26 14:54:43.123 to wróciłoby 2010-11-26 14:54:00.000.

Aby zmienić przedział, na który się zmienia, zastąp 1440.0 liczbą przedziałów w ciągu dnia, na przykład:

24hrs          =   24.0  (for every hour)
24hrs / 0.5hrs =   48.0  (for every half hour)
24hrs / (1/60) = 1440.0  (for every minute)

(zawsze umieszczaj .0 na końcu, aby pośrednio rzucić na pływak.)


Dla tych z Was, którzy zastanawiają się co to jest (3.0/86400000) dla moich obliczeń, SQL Server 2005 nie wydaje się rzucać z FLOAT do DATETIME dokładnie, więc dodaje to 3 milisekundy przed podłogi go.

 0
Author: BG100,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-22 13:03:58

To zapytanie powinno dać wynik równoważny trunc(sysdate) w Oracle.

SELECT  * 
FROM    your_table
WHERE   CONVERT(varchar(12), your_column_name, 101)
      = CONVERT(varchar(12), GETDATE(), 101)
Mam nadzieję, że to pomoże!
 0
Author: Sandeep Gaadhe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-23 15:37:29

Możesz również wyodrębnić datę using Substring ze zmiennej datetime, a przeniesienie z powrotem do datetime zignoruje część czasu.

declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime) 

Możesz również uzyskać dostęp do części zmiennej datetime i połączyć je z obcinaną datą konstrukcji, coś w tym stylu:

SELECT cast(DATENAME(year, @Somedate) + '-' + 
       Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
       DATENAME(day, @Somedate) 
       as datetime)
 0
Author: NeverHopeless,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-07 07:36:41

Wyrocznia:

TRUNC(SYSDATE, 'MONTH')

SQL Server:

DATEADD(DAY, - DATEPART(DAY, DateField) + 1, DateField)

Może być podobnie stosowany do obcinania minut lub godzin od daty.

 0
Author: Markus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 08:46:01

Możesz to zrobić (SQL 2008):

Declare @SomeDate date = getdate ()

select @SomeDate

2009-05-28

 0
Author: Hagai Danenberg-Lerner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-01 15:02:10

TRUNC (ADATE, 'DD') obcina min, sec i hrs

SRC: http://www.techonthenet.com/oracle/functions/trunc_date.php

 -1
Author: Ramnath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-27 12:16:56