it-swarm.com.de

Rufen Sie die Datensätze des letzten Monats in SQL Server ab

Ich möchte die Datensätze des letzten Monats basierend auf meinem Db-Tabelle [member] -Feld "date_created" abrufen.

Was ist die SQL, um dies zu tun?

Zur Verdeutlichung: .__ letzter Monat - 08.01.2009 bis 31.08.2009

Wenn heute der 01.03.2010 ist, brauche ich die Unterlagen vom 12.01.2009 bis 31.12.2009.

61
Billy
SELECT * 
FROM Member
WHERE DATEPART(m, date_created) = DATEPART(m, DATEADD(m, -1, getdate()))
AND DATEPART(yyyy, date_created) = DATEPART(yyyy, DATEADD(m, -1, getdate()))

Sie müssen den Monat und das Jahr überprüfen.

89
Dave Barker

Alle vorhandenen (funktionierenden) Antworten weisen eines von zwei Problemen auf:

  1. Sie ignorieren die Indizes für die zu durchsuchende Spalte
  2. Das wird (möglicherweise) Daten auswählen, die nicht beabsichtigt sind und Ihre Ergebnisse unbemerkt verfälschen.

1. Ignorierte Indizes:

Wenn in einer durchsuchten Spalte eine Funktion aufgerufen wird (einschließlich implizit, wie bei CAST), muss der Optimierer zum größten Teil die Indizes in der Spalte ignorieren und jeden Datensatz durchsuchen. Hier ist ein kurzes Beispiel:

Wir haben es mit Zeitstempeln zu tun, und die meisten RDBMS neigen dazu, diese Informationen als steigenden Wert zu speichern, normalerweise als long oder BIGINTEGER Anzahl von Milli-/Nanosekunden. Die aktuelle Uhrzeit sieht also so aus/wird so gespeichert:

1402401635000000  -- 2014-06-10 12:00:35.000000 GMT

Sie sehen dort nicht den 'Year'-Wert ('2014'), Oder? Tatsächlich gibt es einiges an komplizierter Mathematik, die hin und her übersetzt werden muss. Wenn Sie also eine der Extraktions-/Datumsteilfunktionen für die gesuchte Spalte aufrufen, muss der Server all diese Berechnungen durchführen, um herauszufinden, ob Sie sie in die Ergebnisse einbeziehen können. Bei kleinen Tabellen ist dies kein Problem, aber wenn der Prozentsatz der ausgewählten Zeilen abnimmt, wird dies zu einer immer größeren Belastung. Dann machen Sie es in diesem Fall ein zweites Mal, weil Sie nach MONTH gefragt haben. Nun, Sie bekommen das Bild.

2. Unbeabsichtigte Daten:

Abhängig von der jeweiligen Version von SQL Server und den Spaltendatentypen wird BETWEEN (oder ein ähnlicher eingeschlossener Bereich für die obere Grenze: <=) kann dazu führen, dass die falschen Daten ausgewählt werden =. Im Wesentlichen werden Sie möglicherweise Daten ab Mitternacht des "nächsten" Tages einschließen oder einen Teil der Aufzeichnungen des "aktuellen" Tages ausschließen.

Was du solltest tust:

Wir brauchen also einen Weg, der für unsere Daten sicher ist und Indizes verwendet (sofern möglich). Der richtige Weg ist dann von der Form:

WHERE date_created >= @startOfPreviousMonth AND date_created < @startOfCurrentMonth

Da es nur einen Monat gibt, kann @startOfPreviousMonth Leicht ersetzt/abgeleitet werden durch:

DATEADD(month, -1, @startOCurrentfMonth)

Wenn Sie den Beginn des aktuellen Monats auf dem Server ableiten müssen, können Sie dies folgendermaßen tun:

DATEADD(month, DATEDIFF(month, 0, CURRENT_TIMESTAMP), 0)

Ein kurzes Wort zur Erklärung hier. Die anfängliche DATEDIFF(...) gibt den Unterschied zwischen dem Beginn der aktuellen Ära (0001-01-01 - AD, CE, was auch immer) zurück und gibt im Wesentlichen eine große ganze Zahl zurück. Dies ist die Anzahl der Monate bis zum Beginn des Monats current. Wir addieren diese Zahl dann zum Beginn der Ära, die zu Beginn des jeweiligen Monats liegt.

Ihr vollständiges Skript könnte/sollte also ungefähr so ​​aussehen:

DECLARE @startOfCurrentMonth DATETIME
SET @startOfCurrentMonth = DATEADD(month, DATEDIFF(month, 0, CURRENT_TIMESTAMP), 0)

SELECT *
FROM Member
WHERE date_created >= DATEADD(month, -1, @startOfCurrentMonth) -- this was originally    misspelled
      AND date_created < @startOfCurrentMonth

Alle Datumsoperationen werden daher nur einmal für einen Wert ausgeführt. Es steht dem Optimierer frei, Indizes zu verwenden, und es werden keine falschen Daten eingeschlossen.

78
Clockwork-Muse

Fügen Sie die bisher bereitgestellten Optionen hinzu und verwenden Sie Ihre Indizes nicht.

So etwas tut den Trick und verwendet einen Index für die Tabelle (falls vorhanden).

DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = dateadd(mm, -1, getdate())
SET @StartDate = dateadd(dd, datepart(dd, getdate())*-1, @StartDate)
SET @EndDate = dateadd(mm, 1, @StartDate)

SELECT *
FROM Member
WHERE date_created BETWEEN @StartDate AND @EndDate
12
mrdenny
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = DATEADD(mm, DATEDIFF(mm,0,getdate())-1, 0)
SET @EndDate = DATEADD(mm, 1, @StartDate)

SELECT *
FROM Member
WHERE date_created BETWEEN @StartDate AND @EndDate

Ein Upgrade auf mrdennys Lösung. Auf diese Weise erhalten Sie genau im letzten Monat YYYY-MM-01 

9
Rokas

Betrachten Sie den letzten Monat als bis zum letzten Tag des Monats .. 31.01.2016 hier wäre der letzte Tag des Monats der 31. Januar, der den letzten 30 Tagen nicht ähnlich ist.

SELECT CONVERT(DATE, DATEADD(DAY,-DAY(GETDATE()),GETDATE()))
2
M2012

Eine Möglichkeit ist die Verwendung der Funktion DATEPART :

select field1, field2, fieldN from TABLE where DATEPART(month, date_created) = 4 
and DATEPART(year, date_created) = 2009

wird alle Termine im April zurückgeben. Für den letzten Monat (dh vor dem aktuellen Monat) können Sie auch GETDATE und DATEADD verwenden:

select field1, field2, fieldN from TABLE where DATEPART(month, date_created) 
= (DATEPART(month, GETDATE()) - 1) and 
DATEPART(year, date_created) = DATEPART(year, DATEADD(m, -1, GETDATE()))
2
Vinko Vrsalovic
declare @PrevMonth as nvarchar(256)

SELECT @PrevMonth = DateName( month,DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)) + 
   '-' + substring(DateName( Year, getDate() ) ,3,4)
2
sheetal

Sie können die Datensätze des letzten Monats mit dieser Abfrage abrufen 

SELECT * FROM dbo.member d 
WHERE  CONVERT(DATE, date_created,101)>=CONVERT(DATE,DATEADD(m, datediff(m, 0, current_timestamp)-1, 0)) 
and CONVERT(DATE, date_created,101) < CONVERT(DATE, DATEADD(m, datediff(m, 0, current_timestamp)-1, 0),101) 
DECLARE @StartDate DATETIME, @EndDate DATETIME    
SET @StartDate = DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)    
SET @EndDate = dateadd(dd, -1, DATEADD(mm, 1, @StartDate))

SELECT * FROM Member WHERE date_created BETWEEN @StartDate AND @EndDate 

und ein weiteres Upgrade auf die Lösung von mrdenny.
Es gibt auch den genauen letzten Tag des Vormonats an.

1
Dorothy
WHERE 
    date_created >= DATEADD(MONTH, DATEDIFF(MONTH, 31, CURRENT_TIMESTAMP), 0)
    AND date_created < DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)
1
Kostya
select * from [member] where DatePart("m", date_created) = DatePart("m", DateAdd("m", -1, getdate())) AND DatePart("yyyy", date_created) = DatePart("yyyy", DateAdd("m", -1, getdate()))
1
DmitryK

SQL-Abfrage, um nur den aktuellen Monat zu erfassen

SELECT * FROM CUSTOMER
WHERE MONTH(DATE) = MONTH(CURRENT_TIMESTAMP) AND YEAR(DATE) = YEAR(CURRENT_TIMESTAMP);
1
Mohammad Abraq

Ich bin von Oracle Env und würde es in Oracle so machen:

select * from table
where trunc(somedatefield, 'MONTH') =
trunc(sysdate -INTERVAL '0-1' YEAR TO MONTH, 'MONTH')

Idee: Ich führe einen geplanten Bericht des vorherigen Monats aus (vom ersten Tag bis zum letzten Tag des Monats, nicht mit Fenstern). Dies könnte indexunfreundlich sein, aber Oracle hat sowieso eine schnelle Datumsverarbeitung. Gibt es einen ähnlichen einfachen und kurzen Weg in MS SQL? Die Antwort, die Jahr und Monat getrennt vergleicht, erscheint Oracle-Leuten dumm.

1
ant

Eine einfache Abfrage, die für mich funktioniert, ist:

wählen Sie * aus der Tabelle, in der DATEADD (Monat, 1, DATEFIELD)> = getdate () ist.

0
Harkeet Bajaj

Im letzten SQL-Server:

select * from tablename 
where order_date > DateAdd(WEEK, -1, GETDATE()+1) and order_date<=GETDATE()
0

Ich habe ein ähnliches Problem behoben, indem ich Monat zu meinerSELECTportion hinzugefügt habe

Month DATEADD(day,Created_Date,'1971/12/31') As Month

und dann fügte ichWOAnweisung hinzu

Month DATEADD(day,Created_Date,'1971/12/31') = month(getdate())-1
0
Kalenji
DECLARE @curDate INT = datepart( Month,GETDATE())
IF (@curDate = 1)
    BEGIN
        select * from Featured_Deal
        where datepart( Month,Created_Date)=12 AND datepart(Year,Created_Date) = (datepart(Year,GETDATE())-1)

    END
ELSE
    BEGIN
        select * from Featured_Deal
        where datepart( Month,Created_Date)=(datepart( Month,GETDATE())-1) AND datepart(Year,Created_Date) = datepart(Year,GETDATE())

    END 
0
Kranti Singh
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = dateadd(mm, -1, getdate())
SET @StartDate = dateadd(dd, datepart(dd, getdate())*-1, @StartDate)
SET @EndDate = dateadd(mm, 1, @StartDate)
set @StartDate = DATEADD(dd, 1 , @StartDate)

Wenn Sie letzten Monat suchen, versuchen Sie dies,

SELECT
FROM  #emp 
WHERE DATEDIFF(MONTH,CREATEDDATE,GETDATE()) = 1

Wenn Sie letzten Monat suchen, versuchen Sie dies,

SELECT
FROM #emp
WHERE DATEDIFF(day,CREATEDDATE,GETDATE()) between 1 and 30
0
RIJWAN KASSAR