SQL Server: pobierz dane tylko z ostatniego roku

98

Piszę zapytanie, w którym mam uzyskać dane tylko za ostatni rok. Jaki jest najlepszy sposób, aby to zrobić?

SELECT ... FROM ... WHERE date > '8/27/2007 12:00:00 AM'
Josh Mein
źródło

Odpowiedzi:

196

Następujące polecenie dodaje -1 lat do bieżącej daty:

SELECT ... From ... WHERE date > DATEADD(year,-1,GETDATE())
samjudson
źródło
1
Twoja jest czystsza, ale oto co miałem: ROK (GETDATE ()) - 1
PCPGMR
2
To zwraca liczbę, a nie datę, nie można by było wtedy porównać tego z datą bez obliczenia roku tej daty. To zwróciłoby wówczas nieprawidłowe wyniki za 31 grudnia 2014 r. W porównaniu z 1 stycznia 2015 r. - które są w różnych latach, ale nie są one oddalone od siebie o rok ...
samjudson
poprawny. Musiałem porównać lata po latach, więc na przykład lata 2013-2014, ponieważ napływające dane dotyczyły tylko roku. Nie wyraziłem się jasno w moim komentarzu. Dziękuję
PCPGMR
Otrzymałem komunikat o błędzie podczas wykonywania tego zapytania ... „FUNCTION DatabaseName.DATEADD nie istnieje” Jakieś sugestie?
Marcello Perri
10

Tę stronę znalazłem, szukając rozwiązania, które pomogłoby mi w doborze wyników z poprzedniego roku kalendarzowego. Większość wyników pokazanych powyżej wydaje się zwracać elementy z ostatnich 365 dni, które nie działały w moim przypadku.

Jednocześnie dało mi to wystarczający kierunek, aby rozwiązać moje potrzeby w poniższym kodzie - który zamieszczam tutaj dla wszystkich innych, którzy mają takie same potrzeby jak moje i którzy mogą natknąć się na tę stronę w poszukiwaniu rozwiązania.

SELECT .... FROM .... WHERE year(*your date column*) = year(DATEADD(year,-1,getdate()))

Dziękuję tym, których rozwiązania pomogły mi osiągnąć to, czego potrzebowałem.

DE White
źródło
7

Cóż, myślę, że czegoś tu brakuje. Użytkownik chce uzyskać dane z ostatniego roku, a nie z ostatnich 365 dni. Różnica jest ogromna. Moim zdaniem dane z ostatniego roku to wszystkie dane z 2007 roku (jeśli jestem teraz w 2008 roku). Zatem prawidłowa odpowiedź brzmiałaby:

SELECT ... FROM ... WHERE YEAR(DATE) = YEAR(GETDATE()) - 1

Następnie, jeśli chcesz ograniczyć to zapytanie, możesz dodać inny filtr, ale zawsze w ostatnim roku.

SELECT ... FROM ... WHERE YEAR(DATE) = YEAR(GETDATE()) - 1 AND DATE > '05/05/2007'
Ivan Bosnic
źródło
Będzie to miało bardzo złą wydajność w przypadku dużych tabel, zapytanie będzie zapętlać każdy rekord, aby ocenić wartość roku dla daty, lepiej byłoby użyć zakresu dat
Adriaan Davel
4

Wyszukaj dateadd w BOL

dateadd(yy,-1,getdate())
SQLMenace
źródło
4

Najbardziej czytelny, IMO:

SELECT * FROM TABLE WHERE Date >
   DATEADD(yy, -1, CONVERT(datetime, CONVERT(varchar, GETDATE(), 101)))

Który:

  1. Pobiera teraz datęetime GETDATE () = # 8/27/2008 10:23 am#
  2. Konwertuje na ciąg o formacie 101 CONVERT (varchar, # 8/27/2008 10:23 am#, 101) = '8/27/2007'
  3. Konwertuje na datetime CONVERT (datetime, '8/27/2007') = # 8/27/2008 12:00 AM#
  4. Odejmuje 1 rok DATEADD (rr, -1, # 8/27/2008 12:00 AM#) = # 8/27/2007 12:00 AM#

Istnieją warianty z DATEDIFF i DATEADD, które zapewniają dzisiejszą północ, ale są raczej tępe (choć nieco lepsze pod względem wydajności - nie żebyś zauważył w porównaniu do odczytów wymaganych do pobrania danych).

Mark Brackett
źródło
2

GETDATE () zwraca bieżącą datę i godzinę .

Jeśli ostatni rok zaczyna się o północy bieżącego dnia ubiegłego roku (jak w oryginalnym przykładzie), należy użyć czegoś takiego:

DECLARE @start datetime
SET @start = dbo.getdatewithouttime(DATEADD(year, -1, GETDATE())) -- cut time (hours, minutes, ect.) --  getdatewithouttime() function doesn't exist in MS SQL -- you have to write one
SELECT column1, column2, ..., columnN FROM table WHERE date >= @start
Grzegorz Gierlik
źródło
0

Inne sugestie są dobre, jeśli masz „tylko SQL”.

Sugeruję jednak, aby - jeśli to możliwe - obliczyć datę w swoim programie i wstawić ją jako ciąg w zapytaniu SQL.

Przynajmniej dla dużych tabel (np. Kilka milionów wierszy, być może w połączeniu z łączeniami), co da znaczną poprawę szybkości, ponieważ optymalizator może pracować z tym znacznie lepiej.

BlaM
źródło
2
Byłoby lepiej, gdybyś utworzył sparametryzowany ciąg i uniknął umieszczania wartości w samym ciągu ...
Adriaan Davel
0

argument funkcji DATEADD:

DATEADD (*datepart* , *number* , *date* )

data może być następująca: rr, qq, mm, dy, dd, wk, dw, hh, mi, ss, ms

liczba to wyrażenie, które można przetłumaczyć na liczbę całkowitą, która jest dodawana do części daty

date to wyrażenie, które można przetłumaczyć jako wartość czasu, daty, smalldatetime, datetime, datetime2 lub datetimeoffset.

imtheref
źródło
0
declare @iMonth int
declare @sYear varchar(4)
declare @sMonth varchar(2)
set @iMonth = 0
while @iMonth > -12
begin
    set @sYear = year(DATEADD(month,@iMonth,GETDATE()))
    set @sMonth = right('0'+cast(month(DATEADD(month,@iMonth,GETDATE())) as varchar(2)),2)
    select @sYear + @sMonth
    set @iMonth = @iMonth - 1
end
Tony
źródło
1
To nie odpowiada na pytanie.
Nathan Skerl
Ponadto, chociaż pętle są generalnie złe dla SQL
StingyJack
0

Podobnie jak @DE White, przyjechałem tutaj z podobnych, ale innych powodów niż pierwotne pytanie. Oryginalne pytanie dotyczy ostatnich 365 dni. Zapewnia to odpowiedź @ samjudson. Odpowiedź @DE White zwraca wyniki za poprzedni rok kalendarzowy.

Moje zapytanie jest nieco inne, ponieważ działa w odniesieniu do poprzedniego roku do bieżącej daty włącznie:

SELECT .... FROM .... WHERE year(date) > year(DATEADD(year, -2, GETDATE()))

Na przykład 17 lutego 2017 r. To zapytanie zwraca wyniki od 1 stycznia 2016 r. Do 17 lutego 2017 r

kevinaskevin
źródło
0

Miałem podobny problem, ale poprzedni programista podał datę tylko w formacie mm-rrrr. Moje rozwiązanie jest proste, ale niektórym może okazać się pomocne (chciałem też mieć pewność, że spacje początkowe i końcowe zostały wyeliminowane):

SELECT ... FROM ....WHERE 
CONVERT(datetime,REPLACE(LEFT(LTRIM([MoYr]),2),'-
','')+'/01/'+RIGHT(RTRIM([MoYr]),4)) >=  DATEADD(year,-1,GETDATE())
Rick Savoy
źródło
0

Z jakiegoś powodu żaden z powyższych wyników nie zadziałał dla mnie.

Wybiera ostatnie 365 dni.

 SELECT ... From ... WHERE date BETWEEN CURDATE() - INTERVAL 1 YEAR AND CURDATE()
Connor
źródło
byłoby dobrze, gdybyś mógł dodać wersję serwera MSSQL, dla której to działa.
było