【问题标题】:SQL query to select dates between two datesSQL查询以选择两个日期之间的日期
【发布时间】:2011-07-04 17:58:15
【问题描述】:

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

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

这里的Date 是一个datetime 变量。

【问题讨论】:

    标签: sql sql-server tsql datetime sql-server-2005


    【解决方案1】:

    两件事:

    1. 使用引号

    2. 确保包括最后一天(以 24 结束)

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

    如果Date日期时间

    我倾向于以这种方式进行范围检查,因为它清楚地显示了上下边界。请记住,日期格式在不同的文化中差异很大。所以你可能想确保它被解释为一个日期。使用DATE_FORMAT( Date, 'Y/m/d')

    (提示:使用STR_TO_DATEDATE_FORMAT 切换范例。)

    【讨论】:

      【解决方案2】:

      从 EMP 中选择城市,计数 (EID) 次 出生日期在“31-JAN-1900”和“31-JAN-2900”之间 按城市分组 有计数(EID)> 2;

      这是一个。此查询将查找其 DOB 在指定员工时间范围内出现超过 2 次的城市。

      【讨论】:

      • 不太确定这与 OP 有什么关系。你能详细说明一下吗?
      【解决方案3】:

      我喜欢使用语法 1 MonthName 2015 来表示日期,例如:

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

      dates

      【讨论】:

      • 为什么会这样?
      • 为了让其他开发人员更容易阅读并避免错误,不同国家/地区对日期 dd/mm/yy vs mm/dd/yy 等有不同的格式calendars.wikia.org/wiki/Date_format_by_country
      • March 拼写为 März,我来自哪里
      • 英语也不是我的主要语言,但如果我看到 2011 年 3 月 6 日,我可能会认为那是 2011 年 3 月 6 日,但也可能是 2011 年 6 月 3 日。我不会用我提到的语法犯那个错误
      【解决方案4】:

      实际上,所有 sql 日期都应该采用 yyyy-MM-dd 格式以获得最准确的结果。

      【讨论】:

      • 数据库中的日期是数据库中的日期。在表示层上,您可能想要使用 DATE_FORMATSTR_TO_DATE 函数
      【解决方案5】:

      在根据记录可能具有非零时间值的日期范围进行选择时,此线程中有很多不好的答案和习惯 - 包括撰写本文时的第二高答案。

      永远不要使用这样的代码:Date between '2011/02/25' and '2011/02/27 23:59:59.999'

      或者这个:Date &gt;= '2011/02/25' and Date &lt;= '2011/02/27 23:59:59.999'

      要了解原因,请自行尝试:

      DECLARE @DatetimeValues TABLE
          (MyDatetime datetime);
      INSERT INTO @DatetimeValues VALUES
          ('2011-02-27T23:59:59.997')
          ,('2011-02-28T00:00:00');
      
      SELECT MyDatetime
      FROM @DatetimeValues
      WHERE MyDatetime BETWEEN '2020-01-01T00:00:00' AND '2020-01-01T23:59:59.999';
      
      SELECT MyDatetime
      FROM @DatetimeValues
      WHERE MyDatetime >= '2011-02-25T00:00:00' AND MyDatetime <= '2011-02-27T23:59:59.999';
      

      在这两种情况下,您都会返回两行。假设您正在查看的日期值是旧的 datetime 类型,用于与这些日期进行比较的毫秒值为 999 的日期文字将四舍五入到下一秒的毫秒 000,因为 datetime 并不精确最接近的毫秒。您可以有 997 或 000,但不能介于两者之间。

      可以使用 997 的毫秒值,这将起作用 - 假设您只需要使用 datetime 值,而不是 datetime2 值,因为这些值可以更加精确。例如,在这种情况下,您将错过时间值为 23:59:59.99872 的记录。例如,最初建议的代码也会丢失时间值为 23:59:59.9995 的记录。

      相同答案中提供的另一个解决方案要好得多 - Date &gt;= '2011/02/25' and Date &lt; '2011/02/28'。在这里,无论您查看的是 datetime 还是 datetime2 列都无关紧要,无论如何这都可以。

      我想提出的另一个关键点是日期和时间文字。 '2011/02/25' 不是一个好主意 - 根据您正在使用的系统的设置,这可能会引发错误,因为没有第 25 个月。使用适用于所有地区和语言设置的文字格式,例如'2011-02-25T00:00:00'.

      【讨论】:

      • 哪些是不好的答案或习惯?
      【解决方案6】:

      你应该把这两个日期放在单引号之间,比如..

      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'

      【讨论】:

      • SQL Server 将没有时间的日期默认为 00:00:00。那么这个查询不会返回 2011/02/25 和 2011/02/26 午夜的任何内容吗?
      • @Deepak,你的第二位应该说 >= 和
      • 您可能会提到顺序在 BETWEEN 函数中很重要。它必须从左边最旧的开始,右边是最近的。这是不直观的,因为 = 是 sql 中的比较运算符,适用于 where 子句中的“EmployeeId = 1”或“1 = EmployeeId”。
      • @Matt,根据between 的文档,如果一行的日期为 2011/02/27 而没有时间,则该行的日期为 2011/02/ 27 00:00 并将在查询中返回,因为它小于或等于 2011/02/27 00:00。因此,如果您不考虑时间,between 应该会按预期工作。
      • @timctran 对,但是 2011/02/27 00:00 是我们所说的 2011/02/26 午夜。据推测,查询意味着将 27th 包含在结果集中——但不会包含时间戳为 2011/02/27 5:00 的条目。
      【解决方案7】:
      /****** 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
      

      【讨论】:

      • 我有点迷失为什么其他列在你的答案中
      【解决方案8】:

      试着把日期放在##之间 例如:

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

      它对我有用。

      【讨论】:

      • # 在这种情况下做什么?
      • @B.K.它是一个分隔符,就像字符串的引号一样。 “当为 SQL 语句提供值时,例如作为查询条件,它们的数据类型必须由“限定符”正确定义。这是通过将值括在一对适当的字符之间来完成的。”参考 --> link
      • @B.K.如果它是 TSql 语法,则需要使用单引号 (') 才能获得所需的内容。参考 *basics of sql-fontstuff.com * Beginning SQL - Paul Wilton, John Colby
      • 问题是针对 SQL Server 和 T-SQL 的,这一点再清楚不过了。 T-SQL 和 SQL Server 不接受哈希标记之间的日期,它接受单引号之间的日期。这个答案是错误的。
      • @TT。赞成票的数量表明它仍然对某人有所帮助。在我写答案的时候,已经选择了接受的答案。尽管如此,我写这篇文章是为了帮助任何可能从谷歌或其他地方来到这里的人:)
      【解决方案9】:

      我们可以使用between来显示两个日期数据,但这会搜索整个数据并进行比较,因此对于大量数据会导致我们的处理速度变慢,所以我建议大家使用datediff

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

      这里calender是表格,dt是开始日期变量,dt2是结束日期变量。

      【讨论】:

        【解决方案10】:

        你可以试试这个 SQL

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

        【讨论】:

          【解决方案11】:
          Select 
              * 
          from 
              Calculation 
          where 
              EmployeeId=1 and Date between #2011/02/25# and #2011/02/27#;
          

          【讨论】:

            【解决方案12】:
            select Date,TotalAllowance 
            from Calculation 
            where EmployeeId=1
              and convert(varchar(10),Date,111) between '2011/02/25' and '2011/02/27'
            

            【讨论】:

              【解决方案13】:

              最好这样写:

              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
              

              【讨论】:

              • 在这种情况下使用存储过程没有任何意义,因为它会严重降低 SQL 查询的灵活性,它会非常具体,如果您不想在非常具体的情况下使用它在这种情况下,请不要使用存储过程 - 此外,您的存储过程还有很多改进,您可以在这个社区中找到它们;)。
              【解决方案14】:

              这是非常古老的,但鉴于我在日期方面的很多经验,您可能需要考虑这一点:人们使用不同的区域设置,因此,有些人(以及一些数据库/计算机,取决于区域设置)可以将此日期 11/12/2016 读作 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 服务器不会,所以我总是使用上面的“'”,这两个数据库都接受。

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

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

              我写这篇文章是因为我知道有时一些程序员可能不够敏锐地检测到内在的转换。日期

              对于问的问题,在最后一天的基础上加一天,比较如下:

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

              【讨论】:

              • 您的信息帮助我完成了任务。我已经为此工作了 10 多个小时,但没有一个答案对我有用。当我像你一样连接时,我的项目效果很好。但规则似乎是不要写这样的 SQL 语句。每当我尝试设置 SqlCommand 以将日期参数添加到 SQL 语句时,这些参数将不会附加,并且我得到必须声明“@startDate”和“@endDate”的错误。我无法通过这个问题。我尝试了您的日期格式“dd MMM yyyy”,它有效,我还尝试了“yyyy MMM dd”,它也执行了相同的操作。
              • 太棒了!以上是代码示例。声明和使用参数来避免 SQL 注入总是更好。看来您已经受到项目规则的要求/保护,这很好。
              【解决方案15】:

              我会去

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

              &gt;= 包含整个开始日期,&lt; 不包括结束日期,因此我们在结束日期上添加一个单位。这可以适应几个月,例如:

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

              【讨论】:

                【解决方案16】:

                检查以下示例:工作和非工作。

                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**
                

                【讨论】:

                  【解决方案17】:
                  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
                  

                  【讨论】:

                    【解决方案18】:

                    当前日期和过去三天之间的选择日期的最佳查询:

                      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)   
                    

                    【讨论】:

                      【解决方案19】:

                      如果它的日期在 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'
                      

                      【讨论】:

                        【解决方案20】:

                        由于没有指定时间段的日期时间将具有 date 00:00:00.000 的值,如果您想确保获得范围内的所有日期,您必须提供结束日期的时间或增加结束日期并使用&lt;

                        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'
                        

                        【讨论】:

                        • 人们仍然会查看这些问题和答案,即使它们最初是很久以前提出的。我来寻找答案,我在这里看到的大部分内容都不完整或绝对不正确。我的回答对原发帖者没有帮助,但它可能对某人有所帮助,甚至可能在三年后。
                        • 您的回答对我帮助很大,@WelshDragon -- 其他答案忽略了服务器上的日期格式需要是“简单日期”才能忽略小时的事实。 “
                        • @WelshDragon - 您的回答是使用日期作为 where 子句的非常好的材料。谢谢
                        • 今天试过了,你也可以使用convert(date, Date) between '2011/02/25' and '2011/02/27'(至少使用最近的MS SQL Server)。 convert() 部分将负责剥离时间部分,然后之间的比较将按预期工作。
                        • 不要使用Date &gt;= '2011/02/25' and Date &lt;= '2011/02/27 23:59:59.999',或者介于两者之间的版本。这些都是错误的,将返回值为'2011-02-28T00:00:00' 的记录。也不要太想使用 23:59.59.997 的神奇时间,这更可靠 - 但仅适用于日期时间列。 Datetime2 可以有更高的精度,所以这种比较不是你想要养成的习惯。请改用Date &gt;= '2011-02-25T00:00:00' and Date &lt; '2011-02-28T00:00:00';这个没有缺点。
                        【解决方案21】:
                        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');
                        

                        【讨论】:

                        • 您在编写此答案时可能正在考虑 Oracle SQL。这在 Oracle 中有效。在 SQL Server 中没有那么多(据我所知)。
                        【解决方案22】:

                        此查询适用于获取当前日期与其接下来的 3 个日期之间的值

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

                        这最终会为当前日期增加额外 3 天的缓冲时间。

                        【讨论】:

                          【解决方案23】:
                          select * from test 
                               where CAST(AddTime as datetime) between '2013/4/4' and '2014/4/4'
                          

                          -- 如果数据类型不同

                          【讨论】:

                            【解决方案24】:

                            试试这个:

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

                            日期值需要输入为字符串。

                            为确保您对 SQL Server 2008 及更高版本的查询不会过时,Date 应转义,因为它在更高版本中是保留字。

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

                            【讨论】:

                            • 日期不是关键字,不需要转义。语法高亮只是语法高亮,关键字只有在导致语法错误时才需要转义。使用显式转换而不是日期字符串常量的隐式转换也是一个好习惯。 - 和 CAST('2011/02/25'AS DATETIME) 和 CAST('2011/02/27'AS DATETIME) 之间的日期
                            • 如果这是 OP 标记的 SQL Server 2005,那么您当然是对的。但是,Date 是在 2008 年及以后保留的,因此对于未来的验证,逃避它并没有什么坏处。我已经编辑了我的答案。
                            • 如果他为两者指定单个日期,它将返回零行,但我想这不是 op 的要求
                            猜你喜欢
                            • 2015-04-01
                            • 2016-01-14
                            • 2018-07-25
                            • 2012-03-12
                            • 2013-02-11
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多