我正在尝试从供应商的数据库中导入数据,并将两列合并为我们数据库的一列。它们有两列,分别是CITATION_DATE
数据类型的datetime
和CITATION_TIME
数据类型的char(8)
。
我想将这两列合并为issueDate
数据类型的一列datetime2(7)
。
我尝试使用发现的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;
答案 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