将nvarchar转换为日期时间并返回数据库

时间:2019-04-18 21:15:33

标签: sql sql-server

我收到了一个表格,其中“日期”列被加载为nvarchar(50)。

我或多或少发现将其转换为日期时间。

# fill in NA for missing combinations of x and y before drawing geom_tile
df2 = df %>% complete(x,y)
ggplot(df2, aes(x=x, y=y, fill=z)) + geom_tile(size=0.5, color="black") + scale_fill_brewer(palette="Set1", na.value="white")

但是我遇到一个问题,它没有删除列的“时间”部分。我还将如何将其放回表中,或者仅使用特定的sql代码在表中进行转换。该数据库大约有3000万行,超过160列。

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

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

它只查询所有日期。


*当我转换为日期时间格式101时的查询

enter image description here之后<---------------->在enter image description here之前

3 个答案:

答案 0 :(得分:0)

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

CONVERT(datetime, Date_Time_In, 111)

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

答案 1 :(得分:0)

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

为了创建您有日期的错觉,以便可以使用日期函数,您必须做这样的可怕的事情(由于WHERE谓词由于函数调用):

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)将数据类型固定在当前列上(我知道;遗留系统,相当多的记录等等,使得这不太可能,但是如果可以的话,哇!)

2)将列号161添加为实际上是DATETIME

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

答案 2 :(得分:0)

简短的答案是,您需要将比较的两面都强制转换为相同的日期类型。

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

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