Tsql 将DATETIME列与CHAR字段组合以创建DATETIME2列
我正在尝试从供应商的数据库导入数据,并为我们的数据库将两列合并为一列。它们有两列,分别是Tsql 将DATETIME列与CHAR字段组合以创建DATETIME2列,tsql,datetime,sql-server-2016,Tsql,Datetime,Sql Server 2016,我正在尝试从供应商的数据库导入数据,并为我们的数据库将两列合并为一列。它们有两列,分别是CITATION\u DATE和CITATION\u TIME,前者是char(8)数据类型 我想将这两列合并为一列issueDate,属于datetime2(7)数据类型 我尝试使用Aaron找到的逻辑,但没有成功地执行查询。我的怀疑是我需要更多的字符在引文时间中形成一个有效的时间戳,但我不确定 是否有一种方法可以将这两个字段合并成一个列-遵循datetime2格式 我试图清除空字符串或非数字字符等错误值
CITATION\u DATE
和CITATION\u TIME
,前者是char(8)
数据类型
我想将这两列合并为一列issueDate
,属于datetime2(7)
数据类型
我尝试使用Aaron找到的逻辑,但没有成功地执行查询。我的怀疑是我需要更多的字符在引文时间
中形成一个有效的时间戳,但我不确定
是否有一种方法可以将这两个字段合并成一个列-遵循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数据类型导致值超出范围
看起来我的时间部分没有足够的字符,因为这返回了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;
您是否尝试从时间部分计算分钟数并使用将其添加到日期 此代码假定所有日期都有零时间部分(午夜),引用时间都是数字。上面的代码试图通过强制转换datetime to date(去掉时间部分)并使用try_强制转换来处理非数字时间来处理这些问题。如果需要,可以使用相同的代码:
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
有几个问题。1830年的
引证时间
代表的是06:30:00 PM
,还是以分钟或秒为单位?另外,引用时间的MIN
和MAX
值是多少?这是一个好问题-我假设这是军事时间,但我看到的最大值是9799-因此需要客户提出更多问题。数据清理冒险。让我们知道你发现了什么!最大值9799
让我想知道它是否可能是一天的定点小数:0.9799天=84663秒
。谢谢-引用列中有无效时间-我看到许多值的前两位大于24。
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