【问题标题】:Converting nvarchar to datetime and back into database将 nvarchar 转换为 datetime 并返回到数据库
【发布时间】:2019-04-18 21:15:33
【问题描述】:

我收到了一张表,其中 Date 列被加载为 nvarchar(50)。

我或多或少想出了将其转换为日期时间的方法。

select convert(datetime, Date_Time_In, 101)
FROM [DB].[dbo].[table]

但我遇到了一个问题,它不会删除列的时间部分。另外,我将如何将其放回表中,或者仅使用特定的 sql 代码在表中进行转换。该数据库有大约 3000 万行和 160 多列。

最终目标是尝试对我的数据进行排序,因为我尝试使用以下内容:

SELECT * 
  FROM [DB].[dbo].[table]

  WHERE Date_Time_In between '1/1/2019 01:00:00 PM' and '4/1/2019 01:00:00 PM'

它只是查询所有日期。


*转换成日期时间格式101时的查询

之后之前

【问题讨论】:

  • 你想做什么?你想放弃时间部分吗?然后转换为日期?请不要将其作为字符串保存在数据库中。修复数据库的结构并使用正确的数据类型存储数据。 sqlblog.org/2009/10/12/…

标签: sql sql-server


【解决方案1】:

如果不需要时间部分,请使用

CONVERT(datetime, Date_Time_In, 111)

要替换原始列,请创建一个新列,用转换后的日期填充它,重命名原始列,将原始名称分配给新列。

【讨论】:

    【解决方案2】:

    如果您将日期存储为字符串,日期函数将不起作用。句号。你有文本,而不是日期。

    为了制造你有日期的错觉,以便你可以使用日期函数,你将不得不做一些像这样可怕的事情(这将永远运行,因为 WHERE 谓词由于函数调用而无法 SARGable ):

    SELECT 
      * 
    FROM 
      [DB].[dbo].[table]
    
    WHERE 
      CONVERT(DATETIME, Date_Time_In, 101) 
        BETWEEN '1/1/2019 01:00:00 PM' AND '4/1/2019 01:00:00 PM';
    

    更好的解决方案是:

    1) 修复当前列的数据类型(我知道;遗留系统,很多记录等等,这不太可能,但如果你能做到,WOO HOO!)

    2) 将列号 161 添加为 persisted 计算列,实际上是 DATETIME

    ALTER TABLE [DB].[dbo].[table]
    ADD DateTimeIn AS TRY_PARSE(Date_Time_In AS DATETIME) PERSISTED;
    

    【讨论】:

      【解决方案3】:

      简短的回答是您需要将比较的双方都转换为相同的日期类型。

      长答案是您需要修复该表的基础结构。数据类型非常重要,将所有内容存储为“字符串”只会在有人想要报告该数据时导致问题。我希望下面的例子有助于说明这一点。首先看看时间戳在转换或转换为不同类型时会发生什么。然后看看在比较中使用这些类型时会发生什么。最好不要将时间戳存储为 NVARCHAR(50),而是存储为 DATETIME、DATETIME2 或 DATE,具体取决于您需要的准确度。

      SELECT CAST('1/1/2019 01:00:00 PM' AS DATETIME) betweenStart, 
             CAST('4/1/2019 01:00:00 PM' AS DATETIME) betweenEnd
      SELECT CONVERT(DATETIME, '1/1/2019 01:00:00 PM', 101) betweenStart, 
             CONVERT(DATETIME, '4/1/2019 01:00:00 PM', 101) betweenEnd
      -- betweenStart              betweenEnd
      -- 2019-01-01 13:00:00.000  2019-04-01 13:00:00.000
      
      SELECT CAST('1/1/2019 01:00:00 PM' AS DATETIME2) betweenStart, 
             CAST('4/1/2019 01:00:00 PM' AS DATETIME2) betweenEnd
      SELECT CONVERT(DATETIME2, '1/1/2019 01:00:00 PM', 101) betweenStart, 
             CONVERT(DATETIME2, '4/1/2019 01:00:00 PM', 101) betweenEnd
      -- betweenStart              betweenEnd
      -- 2019-01-01 13:00:00.0000000  2019-04-01 13:00:00.0000000
      
      SELECT CAST('1/1/2019 01:00:00 PM' AS DATE) betweenStart, 
             CAST('4/1/2019 01:00:00 PM' AS DATE) betweenEnd
      SELECT CONVERT(DATE, '1/1/2019 01:00:00 PM', 101) betweenStart, 
             CONVERT(DATE, '4/1/2019 01:00:00 PM', 101) betweenEnd
      -- betweenStart              betweenEnd
      -- 2019-01-01                2019-04-01
      
      IF OBJECT_ID('tempdb..#t') IS NOT NULL
          BEGIN
              DROP TABLE #t
          END
      CREATE TABLE #t(
          myIdCol INT IDENTITY(1,1),
          Date_Time_In NVARCHAR(50)
      )
      INSERT INTO #t
      VALUES('10/24/2018 12:52:10 PM'), 
      ('10/26/2018 3:53:45 PM'), 
      ('10/26/2018 3:53:45 PM'), 
      ('1/1/2019 3:53:45 PM'), 
      ('4/1/2019 12:59:00 PM'), 
      ('4/1/2019 01:00:01 PM')
      
      SELECT * FROM #t WHERE Date_Time_In BETWEEN '1/1/2019 01:00:00 PM' AND '4/1/2019 
      01:00:00 PM'
      --  myIdCol   Date_Time_In
      --  1   10/24/2018 12:52:10 PM
      --  2   10/26/2018 3:53:45 PM
      --  3   10/26/2018 3:53:45 PM
      --  4   1/1/2019 3:53:45 PM
      SELECT * 
      FROM #t 
      WHERE CAST(Date_Time_In AS DATETIME) BETWEEN 
            CAST('1/1/2019 01:00:00 PM' AS DATETIME) 
            AND 
            CAST('4/1/2019 01:00:00 PM' AS DATETIME)
      --  myIdCol Date_Time_In
      --  4   1/1/2019 3:53:45 PM
      --  5   4/1/2019 12:59:00 PM
      SELECT * 
      FROM #t 
      WHERE CAST(Date_Time_In AS DATETIME2) BETWEEN 
            CAST('1/1/2019 01:00:00 PM' AS DATETIME2) 
            AND 
            CAST('4/1/2019 01:00:00 PM' AS DATETIME2)
      --  myIdCol Date_Time_In
      --  4   1/1/2019 3:53:45 PM
      --  5   4/1/2019 12:59:00 PM
      SELECT * 
      FROM #t 
      WHERE CAST(Date_Time_In AS DATE) BETWEEN 
            CAST('1/1/2019 01:00:00 PM' AS DATE) 
            AND 
            CAST('4/1/2019 01:00:00 PM' AS DATE)
      --  myIdCol Date_Time_In
      --  4   1/1/2019 3:53:45 PM
      --  5   4/1/2019 12:59:00 PM
      --  6   4/1/2019 01:00:01 PM
      

      【讨论】:

        猜你喜欢
        • 2016-09-12
        • 2020-10-27
        • 1970-01-01
        • 2012-07-23
        • 2013-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-13
        相关资源
        最近更新 更多