sql - 如何获得日期 + 时间的确定性计算值
问题描述
我有一个表,它有一个日期时间和一个时间字段,其中日期时间实际上只是日期,而时间字段是时间。我需要结合这两个字段来创建一个“created_time”计算字段。我想保留这个计算字段,但是当我尝试组合它们时,我不断收到“非确定性”错误。首先,我不确定我是否理解为什么它是不确定的,但其次,有没有什么奇特的方法可以解决这个问题并实现这一点?
--------------------------------------------------------
date (datetime) | time (varchar)
--------------------------------------------------------
2021-05-05 00:00:00 | 12:00
2021-05-13 00:00:00 | 18:01
我尝试过使用以下计算,但都不起作用。
ALTER TABLE dbo.table ADD created_time AS ([date] + [time]) PERSISTED
ALTER TABLE dbo.table ADD created_time AS (DATEADD(millisecond, DATEDIFF(millisecond, 0, [time]), [date])) PERSISTED
解决方案
首先,操作符对和值+
无效,这看起来很奇怪。所以你需要使用你的第二个版本。date
time
其次,您的time
列实际上是varchar
,因此转换是隐式的非确定性转换。
您可以通过使用确定性样式参数使其CONVERT
具有确定性,例如在本例中为 108:
ALTER TABLE dbo.[table] ADD created_time AS
(DATEADD(millisecond,
DATEDIFF(millisecond, 0, CONVERT(time, [time], 108)),
[date])) PERSISTED;
这在此处记录,一些样式参数不是确定性的,因为它可能取决于文化和世纪(其中年份是两位数)。
我强烈建议您将time
列转换为time
数据类型,或者更好的是,将其更改为组合datetime
列:
ALTER TABLE dbo.[table]
ALTER COLUMN [time] time NOT NULL;
-- or
ALTER TABLE dbo.[table] ADD created_time datetime NULL;
UPDATE dbo.[table]
SET created_time = (DATEADD(millisecond,
DATEDIFF(millisecond, 0, CONVERT(time, [time], 108)),
[date]));
ALTER TABLE dbo.[table]
DROP COLUMN [time]
DROP COLUMN [date];
ALTER TABLE dbo.[table] ALTER created_time datetime NOT NULL;
推荐阅读
- flutter - 没有边距的卡片的 ListView 仍然显示卡片之间的背景
- java - 通过删除 Java 中的前导零来缩短十六进制数
- php - 当我尝试在 Laravel 中发送电子邮件时,htmlspecialchars() 期望参数 1 为字符串
- r - 将数字数据框转换为单个向量
- android - 当 AdView 显示在
- javascript - 循环遍历多维数组最内层循环
- azure - 在 Azure KeyVault 的 ARM 模板中添加 virtualNetworkRules
- sql - 仅查询符合条件的元素
- c# - 使用 NEST C# 在弹性搜索中使用多个索引进行全文搜索
- ruby-on-rails - 为什么我不能在 (OpenStruct) 对象中访问此值?