İki tarih arasındaki tarihleri ​​seçmek için SQL sorgusu


305

Benim bir start_dateve end_date. Bu iki tarih arasındaki tarihlerin listesini almak istiyorum. Birisi sorgumdaki hatayı işaret etmeme yardımcı olabilir.

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

İşte Datebir datetimedeğişken.

Yanıtlar:


487

bu iki tarihi tek tırnak işaretleri arasına koymalısınız.

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

veya kullanabilir

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

ilk tarihin kapsayıcı olduğunu, ancak ikincisinin münhasır olduğunu ve etkin bir şekilde '2011/02/27 00:00:00' olduğunu unutmayın.


42
SQL Server, tarih olmadan 00: 00: 00'da bir tarih kullanır. Peki bu sorgu gece yarısı 2011/02/25 ve 2011/02/26 arasında bir şey döndürmeyecek mi?
Matt

5
@Deepak, ikinci bitiniz> = ve <=
IndoKnight

3
BETWEEN işlevinde siparişin önemli olduğunu belirtebilirsiniz. Soldaki en eskiden ve sağdaki en sondan gitmek zorundadır. = Sql içinde karşılaştırmalı bir işleç olduğu için bu durum kasıtsızdır ve burada yan tümcesinde "EmployeeId = 1" veya "1 = EmployeeId" için çalışır.
Fi Horan

@Matt, belgelerine göre arasında bir satır bir süre olmadan 2011/02/27 bir tarih olsaydı, o zaman bu satır 2011/02/27 00:00 bir tarihe sahip eşdeğerdir ve iade ediyorum sorgu, çünkü 2011/02/27 00:00 değerine eşit veya daha az. Yani zamanla uğraşmıyorsanız, betweenbeklendiği gibi çalışmalısınız.
timctran

@timctran Doğru, ancak 2011/02/27 00:00, 2011/02/26 gece yarısı diyeceğimiz şeydir. Muhtemelen, sorgu 27. kümeyi sonuç kümesine dahil etmek anlamına gelir - ancak 2011/02/27 5:00 zaman damgasına sahip bir giriş dahil edilmez.
Sinjai

128

Belirtilen bir zaman dilimi olmayan bir tarih değeri değerine sahip olacağından date 00:00:00.000, aralığınızdaki tüm tarihleri ​​aldığınızdan emin olmak istiyorsanız, bitiş tarihinizin saatini belirtmeniz veya bitiş tarihinizi ve kullanımınızı artırmanız gerekir <.

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

VEYA

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

VEYA

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

Süreleri 00: 00: 00.000 ise 2011/02/28'den bazı kayıtları döndürebileceğinden aşağıdakileri KULLANMAYIN.

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

42
İnsanlar hala bu sorulara ve cevaplara, bir süre önce ortaya çıkmış olsalar bile bakıyorlar. Bir cevap aramaya geldim ve burada gördüğüm şeylerin çoğu eksik veya kesinlikle yanlıştı. Cevabım asıl postere yardım etmeyecek, ama belki üç yıl sonra bile birine yardımcı olabilir.
WelshDragon

3
Cevabınız bana çok yardımcı oldu, @WelshDragon - Diğer cevaplar, saat biçimini görmezden gelmek için tarih biçiminin sunucuda "basit tarih" olması gerektiğini unuttu. "<= END_DATE", bilmediğim 12AM olduğunu varsayar. "... <= 01/01/2014" ile bir sorgu yapıyordum ve o tarihte siparişlerin neden 1 için gösterilmediğini anlayamadım. Çok teşekkür ederim.
Keith

@WelshDragon - Cevabınız tarihleri ​​nerede cümlecik olarak kullanmak için çok iyi bir malzemedir. Teşekkür ederim
Jack Frost

geri dönerse yanlış olan ne '2011/02/28 00:00:00.000'?
Muflix

1
Bunu bugün denedim, kullanabilirsiniz convert(date, Date) between '2011/02/25' and '2011/02/27'(en azından son bir MS SQL Server ile). convert()Yarı zamanlı parçasını sıyırma ilgilenir ve beklendiği gibi karşılaştırma arasındaki sonra çalışacaktır.
sensei

14

Bunu dene:

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

Tarih değerlerinin dize olarak yazılması gerekir.

SQL Server 2008 ve Datesonraki sürümleri için sorgunuzun gelecekteki provasını sağlamak için , sonraki sürümlerde ayrılmış bir sözcük olduğundan kaçılmalıdır.

Saatleri olmayan tarihlerin gece yarısını varsayılan olarak aldığını unutmayın, bu yüzden orada doğru değere sahip olmayabilirsiniz.


1
Tarih bir anahtar kelime değil ve bu karakterden kaçılmasına gerek yok. Sözdizimi vurgulama sadece sözdizimi vurgulamadır, anahtar kelimelerin yalnızca sözdizimi hatasına neden olmaları durumunda kaçmaları gerekir. Ayrıca, sabitleyici sabitlerin örtük dönüşümü yerine açık dönüşüm kullanmak iyi bir uygulamadır. - ve CAST ('2011/02 / 25'AS DATETIME) ile CAST (' 2011/02 / 27'AS DATETIME) arasındaki tarih
tponthieux

5
Doğal olarak bu OP etiketli SQL Server 2005, haklısın. Ancak, Tarih 2008 ve sonrasında ayrılmıştır, bu nedenle gelecekteki prova için kaçmanın hiçbir zararı yoktur. Cevabımı düzenledim.

1
Her ikisi için de tek bir tarih belirleyecek olsaydı, sıfır satır döndürürdü ama sanırım bu
op'un

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

Burada, ilk önce geçerli 2011-02-28 00:00:00bitiş tarihine bir gün ekleyin, olacaktır , daha sonra bitiş tarihini yapmak için bir saniye çıkarırsınız 2011-02-27 23:59:59. Bunu yaparak, verilen aralıklar arasındaki tüm tarihleri ​​alabilirsiniz.

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


5

Bu sorgu, geçerli tarih ile sonraki 3 tarihi arasındaki değerleri almak için iyi duruyor

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

Bu, sonunda geçerli tarihe fazladan 3 günlük arabellek ekleyecektir.


5

Bu çok eskidir, ancak tarihlerle ilgili yaşadığım birçok deneyim göz önüne alındığında, bunu dikkate almak isteyebilirsiniz: İnsanlar farklı bölgesel ayarları kullanır, örneğin, bazı insanlar (ve bölgesel ayarlara bağlı olarak bazı veritabanları / bilgisayarlar) bunu okuyabilir Tarih 11/12/2016 11 Aralık 2016 veya 12 Kasım 2016 olarak. Daha da fazlası, MySQL veritabanına sağlanan 16/11/12 dahili olarak 12 Kasım 2016'ya dönüştürülürken, İngiltere bölgesel ayar bilgisayarında çalışan Access veritabanı yorumlanır ve 16 Kasım 2012 olarak saklayın.

Bu nedenle, tarihler ve veritabanları ile etkileşime gireceğim zaman politikamı netleştirdim. Bu yüzden her zaman sorgularımı ve programlama kodlarımı aşağıdaki gibi tedarik ederim:

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

Ayrıca Access'in # kabul edeceğini unutmayın:

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

ancak MS SQL sunucusu çalışmaz, bu yüzden her zaman her iki veritabanının da kabul ettiği gibi "" "kullanıyorum.

Ve bu tarihi koddaki bir değişkenden alırken, sonucu her zaman dizeye aşağıdaki gibi dönüştürürüm:

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

Bunu yazıyorum çünkü bazen bazı programcılar doğal dönüşümü algılayacak kadar hevesli olmayabilir. Tarihler <13 için hata olmayacak, sadece farklı sonuçlar olacak!

Sorulan soruya gelince, son tarihe bir gün ekleyin ve karşılaştırmayı aşağıdaki gibi yapın:

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

bilgileriniz görevimin tamamlanmasına yardımcı oldu. Bu konuda 10 saatten fazla çalıştım ve cevaplar benim için işe yaramaz. Gösterdiğin gibi bitirdiğimde projem harika çalışıyor. ancak kural böyle bir SQL ifadesi yazmak gibi görünmüyor. hiç SQL deyimi tarih parametreleri eklemek için SqlCommand's ayarlamaya çalıştığınızda parametreler eklemek olmaz ve ben "@startDate" ve "@ endDate" bildirmek gerekir hatası alıyorum. bu sorunu geçemiyorum. Ben de çalıştım tarih biçimi "dd MMM yyyy" denedim ve aynı zamanda aynı performans "yyyy MMM dd" denedim.
Dave Hampel

Harika yardımcı oldu! Yukarıdaki kod örnekleri. SQL Injection'dan kaçınmak için parametreleri bildirmek ve kullanmak her zaman daha iyidir. Ve projenizdeki kurallar tarafından zaten gerekli / korunuyor gibi görünüyor, ki bu iyi.
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

Tarihleri ​​# # arasına koymayı deneyin, örneğin:

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

Benim için çalıştı.


1
# Bu bağlamda ne yapar?
BK

@BK, dizeler için tırnak işaretleri gibi bir sınırlayıcıdır. Msgstr "Bir SQL ifadesine, örneğin sorgu ölçütleri gibi değerler sağlarken, veri türlerinin" niteleyici "tarafından doğru bir şekilde tanımlanması gerekir. Bu, değeri bir çift uygun karakter arasına alarak yapılır." başvuru -> bağlantı
Aleksandar

1
@BK Bu bir TSql sözdizimiyse, ihtiyacınız olanı elde etmek için tek tırnak işareti ( ' ) kullanmanız gerekir. referanslar * sql-fontstuff.com temelleri * SQL Başlangıcı - Paul Wilton, John Colby
Aleksandar

1
Sorunun SQL Server ve T-SQL için olduğu daha açık olamazdı. T-SQL ve SQL Server, karma etiketler arasındaki tarihleri ​​kabul etmez, tek tırnak işaretleri arasındaki tarihleri ​​kabul eder. Bu cevap yanlış.
TT.

@TT. upvotes sayısı hala birisine yardım ettiğini söylüyor. Cevabımı yazdığım zaman, kabul edilen cevap zaten seçilmişti. Yine de, Google'dan veya başka bir yerden buraya gelebilecek herkese yardımcı olmak için yazdım :)
Aleksandar

2

24 saat içindeki tarihi ve sabah başlayıp gece bitmesi gibi bir şey eklemeniz gerekiyorsa:

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

geçerli tarih ile üç gün arasında bir tarih seçmek için en iyi sorgu :

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

geçerli tarih ile sonraki üç gün arasında tarih seçilmesi için en iyi sorgu :

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

1

Aşağıdaki örnekleri inceleyin: Hem çalışıyor hem de çalışmıyor.

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

VEYA

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

VEYA

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

VE aşağıda çalışmıyor:

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

iki tarih verisini göstermek için kullanabiliriz, ancak bu tüm verileri arar ve karşılaştırır, böylece sürecimizi büyük veriler için yavaşlatır, bu yüzden herkese kullanmasını öneririm datediff:

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

burada takvim Tablo, başlangıç ​​tarihi değişkeni dt ve bitiş tarihi değişkeni dt2'dir.


0

'1 MonthName 2015' sözdizimini eski tarihler için kullanmayı seviyorum:

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

tarihler için


0

Giderdim

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

>=Başlangıç ​​tarihinin tamamını içeren ve <bitiş tarihini hariç tutan mantık , bu nedenle bitiş tarihine bir birim ekleriz. Bu aylarca uyarlanabilir, örneğin:

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

Bu SQL'i deneyebilirsiniz

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

bu şekilde yazmak daha iyi:

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
Bu durumda bir Saklı Yordam kullanmak, SQL sorgusunun esnekliğini korkunç bir şekilde azaltacağı için herhangi bir anlam ifade etmeyecektir, o kadar spesifik olacaktır, Eğer gerçekten belirli bir durumda kullanmak istemiyorsanız, lütfen bir Saklı Yordam - Saklı Yordam için bu toplulukta bulabileceğiniz birçok iyileştirme vardır;).
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
Bu cevabı yazarken muhtemelen Oracle SQL düşünüyordunuz. Bu Oracle için geçerlidir. Çok fazla SQL Server'da (görebildiğim kadarıyla).
Charles Caldwell
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.