SQL-Abfrage zum Auswählen von Daten zwischen zwei Daten


303

Ich habe ein start_dateund end_date. Ich möchte die Liste der Daten zwischen diesen beiden Daten erhalten. Kann mir jemand helfen, den Fehler in meiner Anfrage zu zeigen.

select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and Date between 2011/02/25 and 2011/02/27

Hier Dateist eine datetimeVariable.

Antworten:


484

Sie sollten diese beiden Daten zwischen einfache Anführungszeichen setzen wie ..

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date between '2011/02/25' and '2011/02/27'

oder kann verwenden

select Date, TotalAllowance from Calculation where EmployeeId = 1
             and Date >= '2011/02/25' and Date <= '2011/02/27'

Denken Sie daran, dass das erste Datum inklusive ist, das zweite jedoch exklusiv, da es effektiv "2011/02/27 00:00:00" ist.


42
SQL Server setzt standardmäßig ein Datum ohne Uhrzeit auf 00:00:00. Wird diese Abfrage also nichts vom 25.02.2011 und 26.02.2011 um Mitternacht zurückgeben?
Matt

5
@Deepak, Ihr zweites Bit sollte> = und <=
IndoKnight

3
Sie können erwähnen, dass die Reihenfolge in der Funktion ZWISCHEN von Bedeutung ist. Es muss vom ältesten links und vom jüngeren rechts gehen. Dies ist nicht intuitiv, da = ein Vergleichsoperator in SQL ist und sowohl für "EmployeeId = 1" als auch für "1 = EmployeeId" in der where-Klausel funktioniert.
Fi Horan

@Matt, laut der Dokumentation für zwischendurch , wenn eine Zeile ein Datum vom 27.02.2011 ohne Zeit hatte, dann entspricht diese Zeile einem Datum vom 27.02.2011 00:00 und würde in der zurückgegeben Abfrage, da es kleiner oder gleich 2011/02/27 00:00 ist. Wenn Sie sich also nicht mit Zeit beschäftigen, betweensollten Sie wie erwartet arbeiten.
Timctran

@timctran Richtig, aber 27.02.2011 00:00 ist das, was wir Mitternacht des 26.02.2011 nennen würden. Vermutlich bedeutet die Abfrage, den 27. in die Ergebnismenge aufzunehmen - ein Eintrag mit einem Zeitstempel vom 27.02.2011 um 5:00 Uhr wäre jedoch nicht enthalten.
Sinjai

128

Da eine datetime ohne ein angegebenes Zeitsegment einen Wert von hat date 00:00:00.000 , müssen Sie entweder die Uhrzeit für Ihr Enddatum angeben oder Ihr Enddatum erhöhen und verwenden, wenn Sie sicher sein möchten, dass Sie alle Daten in Ihrem Bereich erhalten <.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/27 23:59:59.999'

ODER

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date < '2011/02/28'

ODER

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date >= '2011/02/25' and Date <= '2011/02/27 23:59:59.999'

Verwenden Sie NICHT das Folgende, da es einige Datensätze vom 28.02.2011 zurückgeben könnte, wenn ihre Zeiten 00: 00: 00.000 sind.

select Date,TotalAllowance from Calculation where EmployeeId=1 
and Date between '2011/02/25' and '2011/02/28'

42
Die Leute schauen sich diese Fragen und Antworten immer noch an, auch wenn sie ursprünglich vor einiger Zeit gestellt wurden. Ich suchte nach einer Antwort und vieles, was ich hier sah, war unvollständig oder absolut falsch. Meine Antwort wird dem Originalplakat nicht helfen, aber es könnte jemandem helfen, vielleicht sogar in drei Jahren.
WelshDragon

3
Ihre Antwort hat mir sehr geholfen, @WelshDragon - Die anderen Antworten haben die Tatsache ausgelassen, dass das Datumsformat "einfaches Datum" auf dem Server sein muss, um die Stunden zu ignorieren. "<= END_DATE" geht von 12 Uhr morgens aus, was ich nicht wusste. Ich habe eine Abfrage mit "... <= 01/01/2014" durchgeführt und konnte nicht herausfinden, warum Bestellungen an diesem Datum für den 1. nicht angezeigt wurden. Vielen Dank.
Keith

@WelshDragon - Ihre Antwort ist ein sehr gutes Material für die Verwendung von Datumsangaben als where-Klausel. Vielen Dank
Jack Frost

Was ist falsch, wenn es zurückkommt '2011/02/28 00:00:00.000'?
Muflix

1
Versucht dies heute, könnten Sie auch verwenden convert(date, Date) between '2011/02/25' and '2011/02/27'(zumindest mit einem aktuellen MS SQL Server). Der convert()Teil kümmert sich um das Entfernen des Zeitteils und der Zwischenvergleich funktioniert dann wie erwartet.
Sensei

14

Versuche dies:

select Date,TotalAllowance from Calculation where EmployeeId=1
             and [Date] between '2011/02/25' and '2011/02/27'

Die Datumswerte müssen als Zeichenfolgen eingegeben werden.

Um sicherzustellen, dass Ihre Abfrage für SQL Server 2008 und höher zukunftssicher ist, Datesollte sie maskiert werden, da sie in späteren Versionen ein reserviertes Wort ist.

Beachten Sie, dass die Daten ohne Uhrzeit standardmäßig Mitternacht sind, sodass Sie dort möglicherweise nicht den richtigen Wert haben.


1
Datum ist kein Schlüsselwort und muss nicht maskiert werden. Syntaxhervorhebung ist nur Syntaxhervorhebung. Schlüsselwörter müssen nur maskiert werden, wenn sie einen Syntaxfehler verursachen. Es wird auch empfohlen, die explizite Konvertierung anstelle der impliziten Konvertierung von Datenringkonstanten zu verwenden. - und Datum zwischen CAST ('2011/02 / 25'AS DATETIME) und CAST (' 2011/02 / 27'AS DATETIME)
tponthieux

5
Natürlich haben Sie Recht, wenn dies SQL Server 2005 ist, den das OP markiert hat. Das Datum ist jedoch ab 2008 reserviert, sodass es für die Zukunftssicherung nicht schadet, ihm zu entkommen. Ich habe meine Antwort bearbeitet.

1
Wenn er das einzelne Datum für beide angeben würde, würde es null Zeilen zurückgeben, aber ich denke, das ist nicht die Anforderung von op
Zo Has

12
select * from table_name where col_Date between '2011/02/25' 
AND DATEADD(s,-1,DATEADD(d,1,'2011/02/27'))

Fügen Sie hier zuerst einen Tag zum aktuellen Enddatum hinzu, 2011-02-28 00:00:00dann subtrahieren Sie eine Sekunde, um das Enddatum festzulegen 2011-02-27 23:59:59. Auf diese Weise können Sie alle Daten zwischen den angegebenen Intervallen abrufen.

output:
2011/02/25
2011/02/26
2011/02/27

8
select * from test 
     where CAST(AddTime as datetime) between '2013/4/4' and '2014/4/4'

- wenn der Datentyp unterschiedlich ist


5

Diese Abfrage eignet sich zum Abrufen der Werte zwischen dem aktuellen Datum und den nächsten drei Daten

SELECT * FROM tableName  WHERE columName 
BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)

Dadurch werden dem aktuellen Datum möglicherweise zusätzliche 3 Tage Puffer hinzugefügt.


5

Dies ist sehr alt, aber angesichts der vielen Erfahrungen, die ich mit Daten gemacht habe, sollten Sie Folgendes berücksichtigen: Benutzer verwenden unterschiedliche regionale Einstellungen. Einige Personen (und einige Datenbanken / Computer, abhängig von den regionalen Einstellungen) lesen dies möglicherweise Datum 11/12/2016 als 11. Dezember 2016 oder 12. November 2016. Darüber hinaus wird der an die MySQL-Datenbank gelieferte 16.11.12 intern in den 12. November 2016 konvertiert, während die auf einem regionalen Einstellungscomputer in Großbritannien ausgeführte Access-Datenbank interpretiert und interpretiert wird Speichern Sie es als 16. November 2012.

Aus diesem Grund habe ich es mir zur Aufgabe gemacht, bei jeder Interaktion mit Daten und Datenbanken explizit zu sein. Daher gebe ich meine Abfragen und Programmiercodes immer wie folgt an:

SELECT FirstName FROM Students WHERE DoB >= '11 Dec 2016';

Beachten Sie auch, dass Access das # akzeptiert, also:

SELECT FirstName FROM Students WHERE DoB >= #11 Dec 2016#;

MS SQL Server wird dies jedoch nicht tun, daher verwende ich immer "'" wie oben, was beide Datenbanken akzeptieren.

Und wenn ich dieses Datum von einer Variablen im Code erhalte, konvertiere ich das Ergebnis immer wie folgt in einen String:

"SELECT FirstName FROM Students WHERE DoB >= " & myDate.ToString("d MMM yyyy")

Ich schreibe dies, weil ich weiß, dass einige Programmierer manchmal nicht scharf genug sind, um die inhärente Konvertierung zu erkennen. Es gibt keinen Fehler für Daten <13, nur unterschiedliche Ergebnisse!

Fügen Sie für die gestellte Frage einen Tag zum letzten Datum hinzu und führen Sie den Vergleich wie folgt durch:

dated >= '11 Nov 2016' AND dated < '15 Nov 2016' 

Ihre Informationen haben dazu beigetragen, meine Aufgabe zu erfüllen. Ich habe mehr als 10 Stunden daran gearbeitet und keine der Antworten würde für mich funktionieren. Wenn ich verkette, wie Sie gezeigt haben, funktioniert mein Projekt großartig. Die Regel scheint jedoch zu sein, eine solche SQL-Anweisung nicht zu schreiben. Wann immer ich versuche, die SqlCommands so einzustellen, dass die Datumsparameter zur SQL-Anweisung hinzugefügt werden, werden die Parameter nicht angehängt und ich erhalte die Fehlermeldung, dass ich "@startDate" und "@endDate" deklarieren muss. Ich kann dieses Problem nicht bestehen. Ich habe Ihr Datumsformat "TT MMM JJJJ" ausprobiert, das funktioniert hat, und ich habe auch "JJJJ MMM TT" ausprobiert, das ebenfalls die gleiche Leistung erbrachte.
Dave Hampel

Großartig, es hat geholfen! Oben sind Codebeispiele. Es ist immer besser, Parameter zu deklarieren und zu verwenden, um SQL Injection zu vermeiden. Und es scheint, dass Sie bereits durch die Regeln in Ihrem Projekt gefordert / geschützt sind, was gut ist.
Hannington Mambo

4
select Date,TotalAllowance 
from Calculation 
where EmployeeId=1
  and convert(varchar(10),Date,111) between '2011/02/25' and '2011/02/27'

3

Versuchen Sie, die Daten zwischen # # zu setzen, zum Beispiel:

#2013/4/4# and #2013/4/20#

Es hat bei mir funktioniert.


1
Was macht # in diesem Zusammenhang?
BK

@BK ist ein Trennzeichen, wie Anführungszeichen für Zeichenfolgen. "Wenn Sie einer SQL-Anweisung Werte bereitstellen, z. B. als Abfragekriterien, muss deren Datentyp durch ein" Qualifikationsmerkmal "korrekt definiert werden. Dazu wird der Wert zwischen zwei entsprechenden Zeichen eingeschlossen." Referenz -> Link
Aleksandar

1
@BK Wenn es sich um eine TSql-Syntax handelt, müssen Sie einfache Anführungszeichen ( ' ) verwenden, um das zu erhalten, was Sie benötigen. Referenzen * Grundlagen von sql-fontstuff.com * Beginn SQL - Paul Wilton, John Colby
Aleksandar

1
Es könnte nicht klarer sein, dass die Frage für SQL Server und T-SQL ist. T-SQL und SQL Server akzeptieren keine Daten zwischen Hash-Tags, sondern Daten zwischen einfachen Anführungszeichen. Diese Antwort ist falsch.
TT.

@TT. Die Anzahl der Upvotes besagt, dass es immer noch jemandem geholfen hat. Zu dem Zeitpunkt, als ich meine Antwort schrieb, war die akzeptierte Antwort bereits ausgewählt. Trotzdem habe ich dies geschrieben, um allen zu helfen, die von Google oder woanders hierher kommen könnten :)
Aleksandar

2

Wenn das Datum in 24 Stunden liegt und am Morgen beginnt und in der Nacht endet, sollte Folgendes hinzugefügt werden:

declare @Approval_date datetime
set @Approval_date =getdate()
Approval_date between @Approval_date +' 00:00:00.000' and @Approval_date +' 23:59:59.999'

1

Beste Abfrage für das ausgewählte Datum zwischen dem aktuellen Datum und drei Tagen zurück :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN       
DATE_SUB(CURDATE(), INTERVAL 3 DAY)  AND CURDATE() 

Beste Abfrage für das ausgewählte Datum zwischen dem aktuellen Datum und den nächsten drei Tagen :

  select Date,TotalAllowance from Calculation where EmployeeId=1 and Date BETWEEN   
   CURDATE()  AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)   

1

Überprüfen Sie die folgenden Beispiele: Sowohl funktionierend als auch nicht funktionierend.

select * from tblUser Where    
convert(varchar(10),CreatedDate,111) between '2015/04/01' and '2016/04/01' //--**Working**

ODER

select * from tblUser Where
(CAST(CreatedDate AS DATETIME) between CAST('2015/04/01' AS DATETIME) And CAST('2016/4/30'AS DATETIME)) //--**Working**

ODER

select * from tblUser Where
(YEAR(CreatedDate) between YEAR('2015/04/01') And YEAR('2016/4/30')) 
//--**Working**

UND unten funktioniert nicht:

select * from tblUser Where
Convert(Varchar(10),CreatedDate,111) >=  Convert(Varchar(10),'01-01-2015',111) and  Convert(Varchar(10),CreatedDate,111) <= Convert(Varchar(10),'31-12-2015',111) //--**Not Working**


select * from tblUser Where
(Convert(Varchar(10),CreatedDate,111) between Convert(Varchar(10),'01-01-2015',111) And Convert(Varchar(10),'31-12-2015',111)) //--**Not Working**

1

Wir können zwischen verwenden, um zwei Datumsdaten anzuzeigen, aber dies durchsucht die gesamten Daten und vergleicht sie, sodass unser Prozess für große Datenmengen langsam wird. Ich empfehle daher jedem, Folgendes zu verwenden datediff:

qry = "SELECT * FROM [calender] WHERE datediff(day,'" & dt & "',[date])>=0 and datediff(day,'" & dt2 & "',[date])<=0 "

Hier ist der Kalender die Tabelle, dt als Variable für das Startdatum und dt2 als Variable für das Enddatum.


0

Ich verwende gerne die Syntax '1 MonthName 2015' für Daten wie:

   WHERE aa.AuditDate>='1 September 2015'
     AND aa.AuditDate<='30 September 2015'

für Termine


0

Ich würde gehen für

select Date,TotalAllowance from Calculation where EmployeeId=1
             and Date >= '2011/02/25' and Date < DATEADD(d, 1, '2011/02/27')

Die Logik besteht darin, dass >=das gesamte Startdatum und <das Enddatum ausgeschlossen werden. Daher fügen wir dem Enddatum eine Einheit hinzu. Dies kann monatelang angepasst werden, zum Beispiel:

select Date, ... from ...
             where Date >= $start_month_day_1 and Date < DATEADD(m, 1, $end_month_day_1)

0
Select 
    * 
from 
    Calculation 
where 
    EmployeeId=1 and Date between #2011/02/25# and #2011/02/27#;

0

Sie können diese SQL versuchen

select * from employee where rec_date between '2017-09-01' and '2017-09-11' 


0
/****** Script for SelectTopNRows command from SSMS  ******/
SELECT TOP 10 [Id]
  ,[Id_parvandeh]
  ,[FirstName]
  ,[LastName]
  ,[RegDate]
  ,[Gilder]
  ,[Nationality]
  ,[Educ]
  ,[PhoneNumber]
  ,[DueInMashhad]

  ,[EzdevajDate]


  ,[MarriageStatus]
  ,[Gender]
  ,[Photo]

  ,[ModifiedOn]
  ,[CreatorIp]
   From
  [dbo].[Socials] where educ >= 3 or EzdevajDate  >= '1992/03/31' and EzdevajDate <= '2019/03/09' and MarriageStatus = 1

-2

es ist besser so zu schreiben:

CREATE PROCEDURE dbo.Get_Data_By_Dates
(
    @EmployeeId INT = 1,
    @Start_Date DATE,
    @End_Date Date
)
AS
Select * FROM Calculation  
    where EmployeeId=@EmployeeId AND Test_Date BETWEEN @Start_Date AND @End_Date
RETURN

1
Die Verwendung einer gespeicherten Prozedur in dieser Situation macht keinen Sinn, da dies die Flexibilität der SQL-Abfrage schrecklich verringert. Sie ist so spezifisch. Wenn Sie sie nicht in einer wirklich spezifischen Situation verwenden möchten, verwenden Sie bitte keine Gespeicherte Prozedur - Es gibt auch viele Verbesserungen für Ihre gespeicherte Prozedur, die Sie in dieser Community finden können;).
shA.t

-6
SELECT Date, TotalAllowance  
FROM Calculation  
WHERE EmployeeId = 1 
  AND Date BETWEEN to_date('2011/02/25','yyyy-mm-dd') 
               AND to_date ('2011/02/27','yyyy-mm-dd');

1
Sie haben wahrscheinlich an Oracle SQL gedacht, als Sie diese Antwort geschrieben haben. Dies gilt in Oracle. Nicht so sehr in SQL Server (soweit ich sehen kann).
Charles Caldwell
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.