แบบสอบถาม SQL เพื่อเลือกวันที่ระหว่างวันที่สองวัน


303

ฉันมีและstart_date end_dateฉันต้องการรับรายการวันที่ระหว่างสองวันนี้ ทุกคนสามารถช่วยชี้ความผิดพลาดในแบบสอบถามได้ไหม

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

นี่Dateคือdatetimeตัวแปร

คำตอบ:


484

คุณควรใส่ทั้งสองวันระหว่างคำพูดเดียวเช่น ..

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

หรือสามารถใช้

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

โปรดทราบว่าวันที่แรกรวมอยู่ด้วย แต่วันที่สองไม่รวมเนื่องจากมีประสิทธิภาพคือ '2011/02/27 00:00:00'


42
SQL Server เริ่มต้นวันที่โดยไม่มีเวลาถึง 00:00:00 ดังนั้นแบบสอบถามนี้จะไม่ส่งคืนสิ่งใดจาก 2011/02/25 และ 2011/02/26 เวลาเที่ยงคืนหรือ
แมตต์

5
@Deepak บิตที่สองของคุณควรจะบอกว่า> = และ <=
IndoKnight

3
คุณอาจพูดถึงว่าลำดับสำคัญในฟังก์ชั่นระหว่าง มันต้องเริ่มจากเก่าที่สุดทางซ้ายและใหม่กว่าทางด้านขวา สิ่งนี้ไม่ได้ใช้งานง่ายเนื่องจาก = เป็นตัวดำเนินการเปรียบเทียบใน sql และใช้ได้กับทั้ง "EmployeeId = 1" หรือ "1 = EmployeeId" ในส่วนคำสั่ง where
Fi Horan

@Matt ตามเอกสารสำหรับระหว่างหากแถวมีวันที่ 2011/02/27 โดยไม่มีเวลาแถวนั้นจะเท่ากับวันที่มี 2011/02/27 00:00 และจะถูกส่งกลับใน ข้อความค้นหาเนื่องจากน้อยกว่าหรือเท่ากับ 2011/02/27 00:00 ดังนั้นหากคุณไม่ได้จัดการกับเวลาbetweenควรทำงานตามที่คาดไว้
timctran

@timctran ใช่แล้ว แต่ 2011/02/27 00:00 คือสิ่งที่เราจะเรียกว่าเที่ยงคืนของปี 2011/02/26 สันนิษฐานว่าแบบสอบถามหมายถึงการรวม 27 ในชุดผลลัพธ์ - แต่รายการที่มีการประทับเวลาของ 2011/02/27 5:00 จะไม่รวม
สินใจ

128

ตั้งแต่วันที่และเวลาโดยไม่ต้องส่วนเวลาที่กำหนดจะมีค่าถ้าคุณต้องการให้แน่ใจว่าคุณจะได้รับทุกวันในช่วงของคุณคุณจะต้องจัดหาเวลาสำหรับวันสิ้นสุดหรือเพิ่มวันสิ้นสุดของคุณและการใช้งานdate 00:00:00.000<

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

หรือ

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

หรือ

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

อย่าใช้ข้อมูลต่อไปนี้เนื่องจากอาจส่งคืนบางระเบียนจาก 2011/02/28 หากเวลาของพวกเขาคือ 00: 00: 00.000

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

42
ผู้คนยังคงดูคำถามและคำตอบเหล่านี้แม้ว่าพวกเขาจะถูกตั้งเวลาไว้บ้าง ฉันมาหาคำตอบและสิ่งที่ฉันเห็นที่นี่ส่วนใหญ่ไม่สมบูรณ์หรือไม่ถูกต้องอย่างแน่นอน คำตอบของฉันจะไม่ช่วยโปสเตอร์ต้นฉบับ แต่อาจช่วยใครซักคนบางทีอาจถึงสามปีจากนี้
WelshDragon

3
คำตอบของคุณช่วยฉันได้อย่างมาก @WelshDragon - คำตอบอื่นที่เหลือจากความจริงที่ว่ารูปแบบวันที่ต้องเป็น "วันที่ง่าย" บนเซิร์ฟเวอร์เพื่อเพิกเฉยต่อชั่วโมง "<= END_DATE" ถือว่า 12AM ซึ่งฉันไม่รู้ ฉันกำลังดำเนินการค้นหาด้วย "... <= 01/01/2014" และฉันไม่สามารถทราบสาเหตุที่คำสั่งซื้อในวันนั้นไม่แสดงในวันที่ 1 ขอบคุณมาก.
Keith

@WelshDragon - คำตอบของคุณเป็นวัสดุที่ดีมากสำหรับการใช้วันที่เป็นส่วนคำสั่ง ขอบคุณ
Jack Frost

เกิดอะไรขึ้นถ้ามันกลับมา '2011/02/28 00:00:00.000'?
Muflix

1
ลองวันนี้คุณสามารถใช้convert(date, Date) between '2011/02/25' and '2011/02/27'(อย่างน้อยกับ MS SQL Server ล่าสุด) convert()ส่วนหนึ่งจะดูแลลอกส่วนเวลาและระหว่างการเปรียบเทียบแล้วจะทำงานตามที่คาดไว้
อาจารย์

14

ลองสิ่งนี้:

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

ค่าวันที่จะต้องพิมพ์เป็นสตริง

เพื่อให้มั่นใจว่าการสืบค้นของคุณในอนาคตสำหรับ SQL Server 2008 และที่สูงกว่านั้นDateควรถูกหลีกเลี่ยงเพราะเป็นคำที่สงวนไว้ในรุ่นที่ใหม่กว่า

โปรดจำไว้ว่าวันที่ไม่มีเวลาใช้เวลาเที่ยงคืนเป็นค่าเริ่มต้นดังนั้นคุณอาจไม่มีค่าที่ถูกต้อง


1
วันที่ไม่ใช่คำหลักและไม่จำเป็นต้องหลบหนี การเน้นไวยากรณ์เป็นเพียงการเน้นไวยากรณ์คำหลักจะต้องได้รับการยกเว้นหากเกิดข้อผิดพลาดทางไวยากรณ์ นอกจากนี้ยังเป็นแนวปฏิบัติที่ดีในการใช้การแปลงที่ชัดเจนแทนการแปลงโดยนัยของค่าคงที่ datestring - และวันที่ระหว่าง CAST ('2011/02 / 25'AS DATETIME) และ CAST (' 2011/02 / 27'AS DATETIME)
tponthieux

5
แน่นอนว่าคุณถูกต้องถ้านี่คือ SQL Server 2005 ซึ่ง OP ติดแท็ก อย่างไรก็ตามวันที่สงวนไว้ในปี 2008 และสูงกว่าดังนั้นสำหรับการพิสูจน์อักษรในอนาคตจึงไม่มีอันตรายใด ๆ ในการหลบหนี ฉันแก้ไขคำตอบของฉันแล้ว

1
ถ้าเขาจะระบุวันที่เดียวสำหรับทั้งคู่มันจะคืนค่าศูนย์แถว แต่ฉันเดาว่าไม่ใช่ความต้องการของ op
Zo มี

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

นี่เป็นครั้งแรกเพิ่มวันไป endDate ปัจจุบันก็จะเป็นแล้วคุณลบคนที่สองที่จะทำให้วันที่สิ้นสุด2011-02-28 00:00:00 2011-02-27 23:59:59ด้วยการทำเช่นนี้คุณจะได้รับวันที่ทั้งหมดระหว่างช่วงเวลาที่กำหนด

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


5

แบบสอบถามนี้มีผลดีในการดึงค่าระหว่างวันที่ปัจจุบันและ 3 วันถัดไป

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

ในที่สุดจะเพิ่มบัฟเฟอร์พิเศษ 3 วันในวันที่ปัจจุบัน


5

นี่เก่ามาก แต่ด้วยประสบการณ์มากมายที่ฉันมีกับวันที่คุณอาจต้องการพิจารณาสิ่งนี้: ผู้คนใช้การตั้งค่าภูมิภาคที่แตกต่างกันเช่นบางคน (และฐานข้อมูล / คอมพิวเตอร์ขึ้นอยู่กับการตั้งค่าภูมิภาค) อาจอ่าน วันที่ 11/12/2559 เมื่อวันที่ 11 ธันวาคม 2559 หรือ 12 พฤศจิกายน 2559 ยิ่งไปกว่านั้น 16/11/12 ที่จัดส่งไปยังฐานข้อมูล MySQL จะถูกแปลงภายในเป็น 12 พฤศจิกายน 2559 ในขณะที่ฐานข้อมูล Access ที่ทำงานบนคอมพิวเตอร์ตั้งค่าภูมิภาคของสหราชอาณาจักรจะตีความและ เก็บไว้ในวันที่ 16 พ.ย. 2555

ดังนั้นฉันจึงกำหนดนโยบายให้ชัดเจนเมื่อใดก็ตามที่ฉันต้องการโต้ตอบกับวันที่และฐานข้อมูล ดังนั้นฉันมักจะให้แบบสอบถามและรหัสการเขียนโปรแกรมดังนี้

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

โปรดทราบว่า Access จะยอมรับ # ดังนั้น:

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

แต่เซิร์ฟเวอร์ MS SQL จะไม่ดังนั้นฉันมักจะใช้ "" "ดังกล่าวข้างต้นซึ่งฐานข้อมูลทั้งสองยอมรับ

และเมื่อได้รับวันที่นั้นจากตัวแปรในรหัสฉันจะแปลงผลลัพธ์เป็นสตริงดังนี้:

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

ฉันเขียนสิ่งนี้เพราะฉันรู้ว่าบางครั้งโปรแกรมเมอร์บางคนอาจไม่กระตือรือร้นที่จะตรวจจับการแปลงโดยธรรมชาติ จะไม่มีข้อผิดพลาดสำหรับวันที่ <13 เพียงผลลัพธ์ที่แตกต่าง!

สำหรับคำถามที่ถามเพิ่มหนึ่งวันเป็นวันสุดท้ายและทำการเปรียบเทียบดังนี้

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

ข้อมูลของคุณช่วยให้งานของฉันสำเร็จ ฉันทำงานเกี่ยวกับเรื่องนี้นานกว่า 10 ชั่วโมงและไม่ใช่คำตอบที่จะทำงานให้ฉัน เมื่อฉันเชื่อมต่อกันเหมือนที่คุณแสดงให้เห็นว่าโครงการของฉันทำงานได้ดีมาก แต่กฎดูเหมือนว่าจะไม่เขียนคำสั่ง SQL เช่นนี้ เมื่อใดก็ตามที่ฉันพยายามตั้งค่า SqlCommand เพื่อเพิ่มพารามิเตอร์วันที่ในคำสั่ง SQL พารามิเตอร์จะไม่แนบและฉันได้รับข้อผิดพลาดที่ฉันต้องประกาศ "@startDate" และ "@endDate" ฉันไม่สามารถผ่านปัญหานี้ได้ ฉันลองรูปแบบวันที่ของคุณ "dd MMM yyyy" ซึ่งใช้งานได้และฉันก็ลอง "yyyy MMM dd" ซึ่งทำเช่นเดียวกัน
Dave Hampel

เยี่ยมมากมันช่วยได้! ด้านบนเป็นตัวอย่างโค้ด เป็นการดีกว่าเสมอที่จะประกาศและใช้พารามิเตอร์เพื่อหลีกเลี่ยง SQL Injection และดูเหมือนว่าคุณจะได้รับการปกป้อง / โดยกฎในโครงการของคุณซึ่งเป็นสิ่งที่ดี
Hannington Mambo


3

ลองใส่วันที่ระหว่าง # # เช่น:

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

มันใช้งานได้สำหรับฉัน


1
# ทำอะไรในบริบทนี้
BK

@BK มันเป็นตัวคั่นเช่นเครื่องหมายคำพูดสำหรับสตริง "เมื่อระบุค่าให้กับคำสั่ง SQL เช่นเป็นเกณฑ์แบบสอบถามชนิดข้อมูลจะต้องกำหนดอย่างถูกต้องโดย" qualifier "ซึ่งทำได้โดยการใส่ค่าระหว่างคู่ของอักขระที่เหมาะสม" การอ้างอิง -> ลิงค์
Aleksandar

1
@BK หากเป็นไวยากรณ์ TSql คุณจะต้องใช้เครื่องหมายคำพูดเดี่ยว ( ' ) เพื่อให้ได้สิ่งที่คุณต้องการ การอ้างอิง * พื้นฐานของ sql-fontstuff.com * SQL เริ่มต้น - Paul Wilton, John Colby
Aleksandar

1
ไม่ชัดเจนว่าคำถามนี้มีไว้สำหรับ SQL Server และ T-SQL T-SQL และ SQL Server ไม่ยอมรับวันที่ระหว่างแท็กแฮชจะยอมรับวันที่ระหว่างเครื่องหมายคำพูดเดี่ยว คำตอบนี้ผิด
TT

@TT จำนวน upvotes บอกว่ามันยังช่วยใครซักคน ในขณะที่ฉันเขียนคำตอบคำตอบที่ตอบถูกเลือกแล้ว ยังฉันเขียนสิ่งนี้เพื่อช่วยให้ทุกคนที่อาจมาที่นี่จาก Google หรือที่อื่น :)
Aleksandar

2

หากวันที่ใน 24 ชั่วโมงและเริ่มในตอนเช้าและสิ้นสุดในตอนกลางคืนควรเพิ่มสิ่งที่ชอบ:

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

แบบสอบถามที่ดีที่สุดสำหรับวันที่เลือกระหว่างวันที่ปัจจุบันและย้อนกลับสามวัน :

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

แบบสอบถามที่ดีที่สุดสำหรับวันที่เลือกระหว่างวันที่ปัจจุบันและสามวันถัดไป :

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

1

ตรวจสอบด้านล่างตัวอย่าง: ทั้งการทำงานและไม่ทำงาน

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

หรือ

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

หรือ

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

และด้านล่างไม่ทำงาน:

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

เราสามารถใช้เพื่อแสดงข้อมูลสองวัน แต่สิ่งนี้จะค้นหาข้อมูลทั้งหมดและเปรียบเทียบดังนั้นมันจะทำให้กระบวนการของเราช้าลงสำหรับข้อมูลขนาดใหญ่ดังนั้นฉันขอแนะนำให้ทุกคนใช้datediff:

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

ที่นี่ปฏิทินคือตาราง, dt เป็นตัวแปรวันที่เริ่มต้นและ dt2 เป็นตัวแปรวันที่สิ้นสุด


0

ฉันชอบที่จะใช้ไวยากรณ์ '1 MonthName 2015' สำหรับวันที่เช่น:

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

สำหรับวันที่


0

ฉันจะไปเพื่อ

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

ตรรกะเป็นสิ่งที่>=มีวันที่เริ่มต้นทั้งหมดและ<ไม่รวมวันที่สิ้นสุดดังนั้นเราจึงเพิ่มหน่วยหนึ่งไปยังวันที่สิ้นสุด สิ่งนี้สามารถปรับตัวได้เป็นเดือนเช่น:

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




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

ควรเขียนด้วยวิธีนี้ดีกว่า:

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
การใช้กระบวนงานที่เก็บไว้ในสถานการณ์นี้จะไม่มีเหตุผลใด ๆ เพราะจะช่วยลดความยืดหยุ่นของแบบสอบถาม SQL ได้อย่างน่ากลัวมันจะเฉพาะเจาะจงมากหากคุณไม่ต้องการใช้ในสถานการณ์ที่เฉพาะเจาะจงจริงๆอย่าใช้ Stored-Procedure - นอกจากนี้ยังมีการปรับปรุงที่ดีขึ้นมากมายสำหรับ Stored-Procedure ของคุณซึ่งคุณสามารถค้นหาได้ในชุมชนนี้;)
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
คุณอาจนึกถึง Oracle SQL เมื่อคุณเขียนคำตอบนี้ สิ่งนี้ใช้ได้ใน Oracle ไม่มากใน SQL Server (จากสิ่งที่ฉันเห็น)
Charles Caldwell
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.