SQL查询以选择两个日期之间的日期


303

我有一个start_dateend_date。我想获取这两个日期之间的日期列表。谁能帮助我指出查询中的错误。

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

Date是一个datetime变量。

Answers:


483

您应该将这两个日期放在单引号之间,例如。

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的任何信息?
马特2012年

5
@Deepak,您的第二行应该说> =和<=
IndoKnight 2013年

3
您可能会提到BETWEEN函数中的顺序很重要。它必须从左侧的最旧的开始,而在右侧的是最近的一次。这是不直观的,因为=是sql中的比较运算符,并且在where子句中适用于“ EmployeeId = 1”或“ 1 = EmployeeId”。
Fi Horan 2015年

@Matt,根据之间的文档,如果某行的日期为2011/02/27而没有时间,则该行等效于日期为2011/02/27 00:00,并将在查询,因为它小于或等于2011/02/27 00:00。因此,如果您不处理时间,则between应按预期工作。
timctran

@timctran是的,但我们称2011/02/26午夜为2011/02/27 00:00。假定查询意味着在结果集中包含第27个-但不会包含时间戳为2011/02/27 5:00的条目。
Sinjai

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'

请勿使用以下内容,因为如果它们的时间为00:00:00.000,则可能会返回2011/02/28起的某些记录。

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

42
人们仍然在看这些问题和答案,即使它们最初是在一段时间后提出来的也是如此。我来寻找答案,而我在这里看到的大部分内容都不完整或绝对不正确。我的回答对原始海报无济于事,但可能会帮助某个人,甚至三年后。
WelshDragon

3
@WelshDragon您的答案对我有很大帮助-其他答案忽略了以下事实:日期格式在服务器上必须为“简单日期”,以忽略小时数。“ <= END_DATE”假设为上午12点,我不知道。我正在用“ ... <= 01/01/2014”执行查询,但我无法弄清楚为什么该日期的订单没有第一次显示。非常感谢你。
基思

@WelshDragon-您的答案是使用日期作为where子句的很好的材料。谢谢
Jack Frost

如果返回, '2011/02/28 00:00:00.000'怎么了?
Muflix '17

1
今天尝试过此方法,您也可以使用convert(date, Date) between '2011/02/25' and '2011/02/27'(至少与最新的MS SQL Server一起使用)。该convert()部分将负责剥离时间部分,并且之间的比较将按预期进行。
–Sensei

14

尝试这个:

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

日期值需要以字符串形式输入。

为了确保您的SQL Server 2008及更高版本的查询Date不会对将来有所影响,应避免使用该查询,因为在更高版本中它是保留字。

请记住,没有时间的日期将以午夜作为默认值,因此您那里可能没有正确的值。


1
日期不是关键字,不需要转义。语法突出显示只是语法突出显示,仅当关键字引起语法错误时才需要转义。使用显式转换而不是日期字符串常量的隐式转换也是一种好习惯。-和CAST('2011/02 / 25'AS DATETIME)和CAST('2011/02 / 27'AS DATETIME)之间的日期
tponthieux

5
如果这是OP标记的SQL Server 2005,那么您自然是对的。但是,Date保留在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

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

-如果数据类型不同


5

该查询非常适合于获取当前日期与其后3个日期之间的值

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

最终,这将为当前日期增加3天的缓冲时间。


5

这很老,但是考虑到我在约会方面的许多经验,您可能要考虑一下:人们使用不同的区域设置,因此,某些人(以及某些数据库/计算机,取决于区域设置)可能会阅读此内容。日期为2016年11月11日,即2016年12月11日或2016年11月12日。提供给MySQL数据库的16/11/12甚至将内部转换为2016年11月12日,而在英国区域设置计算机上运行的Access数据库将解释并将其存储为2012年11月16日。

因此,当我要与日期和数据库进行交互时,我制定了明确的政策。因此,我总是提供如下查询和编程代码:

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

另请注意,Access将接受#,因此:

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

但是MS SQL Server不会,所以我总是像上面那样使用“”,这两个数据库都接受。

从代码中的变量获取日期时,我总是将结果转换为字符串,如下所示:

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

我写这篇文章是因为我知道有时候有些程序员可能并不热衷于检测固有的转换。日期<13不会有错误,只是结果不同!

对于所提问题,将最后一天添加一天,并进行如下比较:

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

您的信息有助于完成我的任务。我已经为此工作了十多个小时,没有一个答案对我有用。当我连接起来就像你已经显示出我的项目效果很好时。但是规则似乎是不要写这样的SQL语句。每当我尝试设置SqlCommand将日期参数添加到SQL语句时,这些参数都不会附加,并且出现错误,我必须声明“ @startDate”和“ @endDate”。我无法通过这个问题。我尝试了有效的日期格式“ dd MMM yyyy”,并且还尝试了同样的“ yyyy MMM dd”。
戴夫·汉佩尔

太棒了!以上是代码示例。最好声明并使用参数以避免SQL注入。看来您已经受到项目中规则的要求/保护,这很好。
汉宁顿曼波

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

3

尝试将日期放在##之间,例如:

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

它为我工作。


1
#在这种情况下会做什么?
BK 2014年

@BK是分隔符,例如字符串的引号。“在向SQL语句提供值(例如,作为查询条件)时,必须由“限定符”正确定义其数据类型。这可以通过将值括在一对适当的字符之间来实现。” 参考-> 链接
Aleksandar 2014年

1
@BK如果是TSql语法,则需要使用单引号(')以获取所需的内容。参考资料* sql-fontstuff.com的基础知识 * 起始SQL-Paul Wilton,John Colby
Aleksandar

1
现在再不清楚这个问题是针对SQL Server和T-SQL的。T-SQL和SQL Server不接受哈希标签之间的日期,而是接受单引号之间的日期。这个答案是错误的。
TT。

@TT。赞成票的数量表明它仍然可以帮助某人。在我写答案时,已经选择了接受的答案。尽管如此,我还是写这篇文章来帮助任何可能从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**

下面的AND不起作用:

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

您可以尝试此SQL

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

最好这样写:

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查询的灵活性,它是如此具体,如果您不想在真正特殊的情况下使用它,请不要使用存储过程-您还可以在此社区找到许多可用于存储过程的改进;)。
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 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.