将DATETIME列与CHAR字段组合以创建DATETIME2列

时间:2018-12-11 18:05:37

标签: tsql datetime sql-server-2016

我正在尝试从供应商的数据库中导入数据,并将两列合并为我们数据库的一列。它们有两列,分别是CITATION_DATE数据类型的datetimeCITATION_TIME数据类型的char(8)

我想将这两列合并为issueDate数据类型的一列datetime2(7)

enter image description here

我尝试使用发现的here的亚伦逻辑,但未能成功执行查询。我怀疑CITATION_TIME中需要更多字符才能形成有效的时间戳,但是我不确定。

有没有一种方法可以将这两个字段合并为一个遵循datetime2格式的列?

我的尝试是尝试清除不良值,例如空字符串或非数字字符:

;WITH issueDate AS
( 
    SELECT 
        TRY_CAST(vt.CITATION_DATE AS DATE) AS CITATION_DATE ,
        CASE WHEN RTRIM ( LTRIM ( vt.CITATION_TIME )) = '' THEN '0000'
             WHEN RTRIM ( LTRIM ( vt.CITATION_TIME )) = '000' THEN '0000'
             WHEN TRY_CAST(vt.CITATION_TIME AS INT) IS NULL THEN '0000'
             ELSE vt.CITATION_TIME
        END AS CITATION_TIME
    FROM   
        Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS AS vt
    --ORDER BY CITATION_TIME;
)
SELECT 
    CONVERT(DATETIME, CONVERT(CHAR(8), id.CITATION_DATE, 112) + ' ' + 
       CONVERT(CHAR(8), id.CITATION_TIME, 108))
FROM   
    issueDate AS id;

但是我遇到以下错误:

  

将varchar数据类型转换为datetime数据类型会导致值超出范围

看起来我没有足够的字符用于TIME部分-因为它以DATETIME格式返回值,但是我以这种方式失去了所有的小时和分钟:

;WITH issueDate AS 
(
    SELECT 
        TRY_CAST(vt.CITATION_DATE AS DATE) AS CITATION_DATE,
        CASE 
           WHEN RTRIM(LTRIM(vt.CITATION_TIME)) = '' THEN '00:00:00.0000000'
           WHEN RTRIM(LTRIM(vt.CITATION_TIME)) = '000' THEN '00:00:00.0000000'
           WHEN TRY_CAST(vt.CITATION_TIME AS INT) IS NULL THEN '00:00:00.0000000'
           --ELSE vt.CITATION_TIME
        END AS CITATION_TIME
    FROM   
        Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS AS vt
    --ORDER BY CITATION_TIME;
)
SELECT 
    CONVERT(DATETIME, CONVERT(CHAR(8), id.CITATION_DATE, 112) + ' ' +
        CONVERT(CHAR(8), id.CITATION_TIME, 108)) AS [DateTime]
FROM   
    issueDate AS id
WHERE
    CONVERT(DATETIME, CONVERT(CHAR(8), id.CITATION_DATE, 112) + ' ' +
        CONVERT(CHAR(8), id.CITATION_TIME, 108)) IS NOT NULL;

1 个答案:

答案 0 :(得分:0)

您是否尝试计算时间部分的分钟数,并使用DATEADD将其添加到日期?

select DATEADD(minute, cast(CITATION_TIME as int) % 100 + 60 * (cast(CITATION_TIME as int) / 100), CITATION_DATE)
FROM   Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS AS vt

此代码假定所有日期的时间部分为零(午夜),并且CITATION_TIME是全数字。上面的代码尝试通过将datetime转换为date(以摆脱时间部分)并使用try_cast处理非数字时间来处理这些问题。如果需要,可以使用相同的代码:

select DATEADD(minute, t.IntTime % 100 + 60 * (t.IntTime / 100), cast(CITATION_DATE as date))
FROM   Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS AS vt
cross apply (select isnull(try_cast(CITATION_TIME as int), 0) as IntTime ) t

如果数据中有无效的“时间”,则必须决定如何处理它们。尝试通过搜索值来查找这些记录,例如最后2位数字> = 60,

select * from Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS
where try_cast(right(CITATION_TIME, 2) as int) >= 60
   or (len(CITATION_TIME) = 4 and try_cast(left(CITATION_TIME, 2) as int) >= 24)       
   or len(CITATION_TIME) > 4