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'

Odpowiedzi:


196

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

SELECT ... From ... WHERE date > DATEADD(year,-1,GETDATE())

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.


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'

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

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).


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

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.


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.


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

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


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())

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()

byłoby dobrze, gdybyś mógł dodać wersję serwera MSSQL, dla której to działa.
było
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.