【问题标题】:Compare a date string to datetime in SQL Server?将日期字符串与 SQL Server 中的日期时间进行比较?
【发布时间】:2010-09-05 20:46:55
【问题描述】:

在 SQL Server 中,我有一个 DATETIME 列,其中包含一个时间元素。

例子:

'14 AUG 2008 14:23:019'

什么是最佳方法只选择特定日期的记录,忽略时间部分?

示例:(不安全,因为它与时间部分不匹配并且不返回任何行)

DECLARE  @p_date DATETIME
SET      @p_date = CONVERT( DATETIME, '14 AUG 2008', 106 )

SELECT *
FROM   table1
WHERE  column_datetime = @p_date

注意:鉴于这个网站也是关于记下你拿起然后忘记的笔记和技术,我将发布我自己对这个问题的答案,因为 MSSQL 中的 DATETIME 内容可能是我查找最多的主题在 SQLBOL 中。


更新更具体的澄清示例。


编辑抱歉,我不得不修改错误答案(返回错误结果的答案)。

@Jorrit:WHERE (date>'20080813' AND date<'20080815') 将返回 13 号和 14 号。

@wearejimbo:关闭,但没有雪茄! 授予您徽章。您错过了 2008 年 8 月 14 日 23:59:001 到 23:59:999(即午夜前不到 1 秒)写入的记录。

【问题讨论】:

    标签: sql-server database tsql datetime


    【解决方案1】:

    SQL 中有多种日期格式被指定。参考https://msdn.microsoft.com/en-in/library/ms187928.aspx

    将 varchar 列与选定日期进行转换和比较。

    语法:

    SELECT * FROM tablename where CONVERT(datetime,columnname,103) 
        between '2016-03-01' and '2016-03-03'
    
    In CONVERT(DATETIME,COLUMNNAME,103) "103" SPECIFIES THE DATE FORMAT as dd/mm/yyyy
    

    【讨论】:

      【解决方案2】:
      SELECT CONVERT(VARCHAR(2),DATEPART("dd",doj)) + 
          '/' + CONVERT(VARCHAR(2),DATEPART("mm",doj)) + 
          '/' + CONVERT(VARCHAR(4),DATEPART("yy",doj)) FROM emp
      

      【讨论】:

        【解决方案3】:
        SELECT * FROM tablename
        WHERE CAST(FLOOR(CAST(column_datetime AS FLOAT))AS DATETIME) = '30 jan 2012'
        

        【讨论】:

          【解决方案4】:
          DECLARE @Dat
          
          SELECT * 
          FROM Jai
          WHERE                                                                                                          
          CONVERT(VARCHAR(2),DATEPART("dd",Date)) +'/'+                                                              
                       CONVERT(VARCHAR(2),DATEPART("mm",Date)) +'/'+              
                               CONVERT(VARCHAR(4), DATEPART("yy",Date)) = @Dat
          

          【讨论】:

            【解决方案5】:

            在sqlserver中

            DECLARE @p_date DATE
            
            SELECT * 
            FROM table1
            WHERE column_dateTime=@p_date
            

            在 C# 中 使用 ToShortDateString() 函数传递日期值的短字符串。 样本: DateVariable.ToShortDateString();

            【讨论】:

              【解决方案6】:

              最好的方法是使用 SQL DATE() 函数简单地提取日期部分:

              SELECT * 
              FROM table1
              WHERE DATE(column_datetime) = @p_date;
              

              【讨论】:

                【解决方案7】:

                技巧一:

                 DECLARE @p_date DATETIME
                 SET     @p_date = CONVERT( DATETIME, '14 AUG 2008', 106 )
                
                 SELECT  *
                 FROM    table1
                 WHERE   column_datetime >= @p_date
                 AND     column_datetime < DATEADD(d, 1, @p_date)
                

                这样做的好处是它将使用“column_datetime”上的任何索引(如果存在)。

                【讨论】:

                • 我相信 CAST('14 AUG 2008' as DateTime) 稍微好一点。我认为它更具可读性,并且我相信 CAST 比 CONVERT() 更便携,因为 CAST() 与 ANSI SQL-92 和 -99 兼容
                • 您可以使用 BETWEEN 关键字作为此答案的简写。
                • @BorhanMooz,实际上,BETWEEN 没有捕获代码中给出的 >= / technet.microsoft.com/en-us/library/ms187922.aspx,“结果值”)。
                【解决方案8】:

                我通常将日期时间转换为日期并比较它们,如下所示:

                SELECT 'Same Date' WHERE CAST(getDate() as date) = cast('2/24/2012 2:23 PM' as date)
                

                SELECT 'Same Date' WHERE DATEDIFF(dd, cast(getDate() as date), cast('2/24/2012 2:23 PM' as date)) = 0
                

                【讨论】:

                  【解决方案9】:

                  日期可以在 sqlserver 中使用字符串比较进行比较: 例如

                  DECLARE @strDate VARCHAR(15)
                  SET @strDate ='07-12-2010'
                  
                  
                  SELECT * FROM table
                  WHERE CONVERT(VARCHAR(15),dtInvoice, 112)>= CONVERT(VARCHAR(15),@strDate , 112)
                  

                  【讨论】:

                    【解决方案10】:

                    关于您接受的答案中的索引的要点。

                    不过,如果您真的只搜索特定的 DATEDATE ranges经常,那么我发现的最佳解决方案是在您的表中添加另一个仅包含 @ 的持久计算列987654323@,并在此列添加索引:

                    ALTER TABLE "table1" 
                        ADD "column_date" AS CONVERT(DATE, "column_datetime") PERSISTED
                    

                    在该列上添加索引:

                    CREATE NONCLUSTERED INDEX "table1_column_date_nu_nci"
                    ON  "table1" ( "column_date" ASC )
                    GO
                    

                    那么你的搜索会更快:

                    DECLARE  @p_date DATE
                    SET      @p_date = CONVERT( DATE, '14 AUG 2008', 106 )
                    
                    SELECT   *
                    FROM     table1
                    WHERE    column_date = @p_date
                    

                    【讨论】:

                    • 然后,我建议对大多数数据库识别且不依赖于语言/区域设置的日期使用一种 ISO 格式,例如 YYYY-MM-DD
                    【解决方案11】:

                    如何在 MS SQL Server 中获取 DATETIME 字段的 DATE 部分:

                    最快捷、最简洁的方法之一就是使用

                    DATEADD(dd, DATEDIFF( dd, 0, @DAY ), 0)
                    

                    它避免了CPU破坏“将日期转换为没有时间的字符串然后再将其转换回来”的逻辑。

                    它也没有公开“时间部分表示为日期的一部分”的内部实现。

                    获取当月第一天的日期

                    DATEADD(dd, DATEDIFF( dd, -1, GetDate() - DAY(GetDate()) ), 0)
                    

                    获取 1 年前的日期

                    DATEADD(m,-12,DATEADD(dd, DATEDIFF( dd, -1, GetDate() - DAY(GetDate()) ), 0))
                    

                    【讨论】:

                      【解决方案12】:

                      在 SQL Server 2008 中,您可以使用新的 DATE 数据类型

                      DECLARE @pDate DATE='2008-08-14'  
                      
                      SELECT colA, colB
                      FROM table1
                      WHERE convert(date, colDateTime) = @pDate  
                      

                      @盖伊。我想你会发现这个解决方案可以很好地扩展。查看原始查询的query execution plan

                      对于mine

                      【讨论】:

                        【解决方案13】:
                        SELECT  *
                        FROM    table1
                        WHERE   CONVERT(varchar(10),columnDatetime,121) = 
                                CONVERT(varchar(10),CONVERT('14 AUG 2008' ,smalldatetime),121)
                        

                        这会将数据时间和字符串转换为“YYYY-MM-DD”格式的varchars。

                        这很丑陋,但应该可以工作

                        【讨论】:

                          【解决方案14】:

                          这个函数Cast(Floor(Cast(GetDate() As Float)) As DateTime)返回一个删除了时间部分的日期时间数据类型,可以这样使用。

                          Select
                          *
                          Table1
                          Where
                          Cast(Floor(Cast(Column_DateTime As Float)) As DateTime) = '14-AUG-2008'
                          

                          DECLARE  @p_date DATETIME
                          SET      @p_date = Cast('14 AUG 2008' as DateTime)
                          
                          SELECT   *
                          FROM     table1
                          WHERE    Cast(Floor(Cast(column_datetime As Float)) As DateTime) = @p_date
                          

                          【讨论】:

                          • 应用于字段的多个函数(如果已建立索引)不会将其转换为全表扫描吗?
                          【解决方案15】:

                          技巧2:

                          DECLARE @p_date DATETIME
                          SET     @p_date = CONVERT( DATETIME, '14 AUG 2008', 106 )
                          
                          SELECT  *
                          FROM    table1
                          WHERE   DATEDIFF( d, column_datetime, @p_date ) = 0
                          

                          如果 column_datetime 字段没有被索引,并且不太可能被索引(或者索引不太可能被使用),那么使用 DATEDIFF() 会更短。

                          【讨论】:

                            【解决方案16】:

                            这样的?

                            SELECT  *
                            FROM    table1
                            WHERE   convert(varchar, column_datetime, 111) = '2008/08/14'
                            

                            【讨论】:

                              【解决方案17】:

                              我知道这不是您想要的方式,但这可能是一个开始:

                              SELECT *
                              FROM (SELECT *, DATEPART(yy, column_dateTime) as Year, 
                                    DATEPART(mm, column_dateTime) as Month, 
                                    DATEPART(dd, column_dateTime) as Day 
                                    FROM table1)
                              WHERE Year = '2008'
                              AND Month = '8'
                              AND Day = '14'
                              

                              【讨论】:

                                【解决方案18】:

                                只需比较年、月和日的值。

                                Declare @DateToSearch DateTime
                                Set @DateToSearch = '14 AUG 2008'
                                
                                SELECT * 
                                FROM table1
                                WHERE Year(column_datetime) = Year(@DateToSearch)
                                      AND Month(column_datetime) = Month(@DateToSearch)
                                      AND Day(column_datetime) = Day(@DateToSearch)
                                

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 2016-10-08
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2013-06-28
                                  • 2013-04-08
                                  • 2021-10-07
                                  • 2022-01-16
                                  • 2022-11-21
                                  相关资源
                                  最近更新 更多