【问题标题】:Date is string between hyphens in SQL Server日期是 SQL Server 中连字符之间的字符串
【发布时间】:2017-11-01 12:57:37
【问题描述】:

我的日期格式如下:

Date_str
19-12-2007
31-7-2009
3-1-2010
31-11-2009
etc.

我无法执行以下操作:

CONCAT(RIGHT(Date_str,4),SUBSTRING(Date_str,3,3),LEFT(2)) 

因为正如您在上面看到的,日期的长度不同。 SQL Server 中有没有办法将日期提取为日期时间/日期?

我也试过

Convert(datetime, Date_str)

但它只是抛出了一个错误:

导致将 varchar 数据类型转换为 datetime 数据类型 在一个超出范围的值。

【问题讨论】:

  • 将它们存储为 'YYYY-MM-DD' 并在所有 SQL 风格中避免这种情况 :)
  • 日期类型没有格式。只是不要将日期存储为字符串
  • @scsimon 相反,使用正确的日期类型并避免任何问题。存储为字符串,您将永远无法修复所有错误。例如,尝试在该字符串中添加一天。或检索月份 name
  • @PRIME 问题是您使用了错误的类型来存储日期。唯一现实的解决方案是使用正确的类型,date。您只需转换一次本地化数据,之后您就不必担心转换和格式
  • 好吧,我没有,其他人这样存储它,我必须使用它..

标签: sql sql-server tsql datetime


【解决方案1】:

请参阅https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql 了解日期格式

你可能需要

CONVERT(DateTime, Date_str, 105)

【讨论】:

    【解决方案2】:

    如果 2012+,我会使用 Try_Convert()。这会将虚假日期返回为 NULL。

    示例

    Declare @YourTable Table ([Date_str] varchar(50))
    Insert Into @YourTable Values
     ('19-12-2007')
    ,('31-7-2009')
    ,('3-1-2010')
    ,('31-11-2009')
    
    Select *
          ,try_convert(date,Date_Str,105) 
     from @YourTable
    

    退货

    Date_str    (No column name)
    19-12-2007  2007-12-19
    31-7-2009   2009-07-31
    3-1-2010    2010-01-03
    31-11-2009  NULL             -- Notice 11/31 is NOT a date
    

    【讨论】:

    • 不错的约翰卡帕莱蒂!我只是在 SELECT 语句中使用它: SELECT TRY_CONVERT(datetime, Date_str,105) FROM TABLE
    • @PRIME Try_Convert 可以让事情变得更简单。众所周知,当日期被存储为刺时......一大堆可能会出错。 :)
    【解决方案3】:

    正如我在 cmets 中提到的,唯一现实的解决方案是将该字符串转换为正确的 date-typed 列。当前格式不允许日期排序或搜索一系列日期,例如查找上周的条目,或一个日期与另一个日期之间的条目。

    使用CONVERTTRY_PARSE 解析意味着不能使用索引来加速查询。每次:

    WHERE CONVERT(Date, Date_str, 105) > '20170101'
    

    使用时,服务器必须扫描整个表以转换数据,然后过滤行。

    如果您无法更改字段本身的类型,则可以创建一个持久计算列,该列将值作为日期返回并为其添加索引。您将能够使用该列进行索引查询:

    alter table SomeTable add date2 as TRY_convert(Actual_Date,date_str,105) PERSISTED
    
    create index IX_SomeTable_ActualDate on SomeTable (Actual_Date)
    

    这将使您无需技巧即可执行排序:

    SELECT * 
    FROM SomeTable
    ORDER BY Actual_Date
    

    或运行利用 IX_SomeTable_ActualDate 索引的范围查询:

    SELECT * 
    FROM SomeTable
    Where Actual_Date Between DATEADD(d,-7,GETDATE()) AND GETDATE()
    

    如果您有 1000 行,您可以获得 1000 倍的性能。

    现有应用程序甚至不会注意到更改。较新的查询和应用程序将能够利用索引和排序

    【讨论】:

      【解决方案4】:

      我遇到了类似的问题:我的列 () 的日期值格式为

      2021-01
      2021-02
      2021-10
      2021-12
      

      等等,数据类型为 nvarchar(4000),我总是遇到Conversion failed when converting date and/or time from character string. 错误(例如在尝试CAST(<my_date_field> AS DATE)CAST(CAST(<my_date_field> AS VARCHAR(7)) AS DATE) 等时)

      我能够使用以下代码将它们转换为日期:

      SELECT
      CONVERT(date, <my_date_field> + '-01') AS first_day_of_month
      FROM my_table
      

      导致

      2021-08-01
      2021-07-01
      2021-06-01
      2021-05-01
      

      【讨论】:

        猜你喜欢
        • 2017-12-16
        • 2012-10-04
        • 2021-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-31
        • 1970-01-01
        • 2021-06-26
        相关资源
        最近更新 更多