如何将一个字段中的日期与另一字段中的时间结合起来 - MS SQL Server
Posted
技术标签:
【中文标题】如何将一个字段中的日期与另一字段中的时间结合起来 - MS SQL Server【英文标题】:How to combine date from one field with time from another field - MS SQL Server 【发布时间】:2010-10-16 13:59:25 【问题描述】:在我正在处理的摘录中,我有 2 个datetime
列。如图所示,一列存储日期,另一列存储时间。
如何查询表以将这两个字段合并为 1 列类型为datetime
?
日期
2009-03-12 00:00:00.000
2009-03-26 00:00:00.000
2009-03-26 00:00:00.000
时代
1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
【问题讨论】:
【参考方案1】:您可以简单地将两者相加。
如果您的Date
列的Time part
始终为零
并且Time
列的Date part
也始终为零(基准日期:1900 年 1 月 1 日)
添加它们会返回正确的结果。
SELECT Combined = MyDate + MyTime FROM MyTable
基本原理(感谢 ErikE/dnolan)
由于日期存储为两个 4 字节的方式,它的工作原理是这样的
Integers
,左边 4 字节是date
,右边 4 字节为time
。就像在做$0001 0000 + $0000 0001 = $0001 0001
关于新的 SQL Server 2008 类型的编辑
Date
和Time
是SQL Server 2008
中引入的类型。如果你坚持要添加,可以使用Combined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)
Edit2 关于 SQL Server 2008 及更高版本中的精度损失(感谢 Martin Smith)
查看How to combine date and time to datetime2 in SQL Server? 以防止在使用 SQL Server 2008 及更高版本时丢失精度。
【讨论】:
@Jon,只要日期列的时间元素和时间列的日期元素都为零,就可以了。 您很可能会遇到这里描述的内容groups.google.be/group/…borland*+author%3Ateamb*#1ab62659d8be3135 SQL Server 中的“零”日期是1900-01-01
,不是吗?
当我尝试这个时,我不需要将“时间”值转换为日期时间。换句话说,您可以这样做:日期时间 + 时间
SQL Server 中的@dnolan 日期不存储为float
。这到底是从哪里学来的?它们存储为整数:日期部分是自锚定日期以来的天数,时间部分是自午夜以来的“滴答”数,对于@,滴答定义为 1/300 秒987654338@ 和 time
和 datetime2
更精确。【参考方案2】:
如果您的日期列的时间元素和您的时间列的日期元素都为零,那么Lieven's answer 就是您所需要的。如果你不能保证永远都是这样,那么它会变得稍微复杂一些:
SELECT DATEADD(day, 0, DATEDIFF(day, 0, your_date_column)) +
DATEADD(day, 0 - DATEDIFF(day, 0, your_time_column), your_time_column)
FROM your_table
【讨论】:
感谢卢克的回答。幸运的是,在这种情况下,我可以保证其他项目始终为零,我认为这 2 个字段甚至可能是 1 在为我们提取数据的第三方代码的另一侧。 我遇到了和 OP 一样的问题,只是我知道不需要的部分永远不会为零。因此,这非常有用,如果我能投票给你两次,我会的! 这救了我!我将两者都转换为字符,然后连接,然后返回 DATETIME,但后来我无法索引它,因为 SQL 说它是不确定的。这显然是确定性的!!!谢谢 !!!你!!! 您的 SQL Server 2008 版本不起作用。The data types datetime and time are incompatible in the add operator.
@Martin:我已经删除了损坏的 SQL2008 版本。【参考方案3】:
这是没有任何字符转换的替代解决方案:
DATEADD(ms, DATEDIFF(ms, '00:00:00', [Time]), CONVERT(DATETIME, [Date]))
您只能通过这种方式获得毫秒级的精度,但这通常是可以的。我已经在 SQL Server 2008 中对此进行了测试。
【讨论】:
【参考方案4】:这对我有用
CAST(Tbl.date as DATETIME) + CAST(Tbl.TimeFrom AS TIME)
(在 SQL 2008 R2 上)
【讨论】:
在 SQL Server 2008 中运行良好。 我得到数据类型 datetime 和 time 在 add 运算符中不兼容。 SQL Server 2012 上的错误 SQL 2012 数据类型 datetime 和 time 在 add 运算符中不兼容 这不再适用于 SQL Server 2012 及更高版本(重大更改)。详情见这里:social.msdn.microsoft.com/forums/azure/en-US/… 它也不适用于 SQL Server 2019 (15)。【参考方案5】:如果您不使用 SQL Server 2008(即您只有一个 DateTime 数据类型),您可以使用以下(公认的粗略和现成的)TSQL 来实现您想要的:
DECLARE @DateOnly AS datetime
DECLARE @TimeOnly AS datetime
SET @DateOnly = '07 aug 2009 00:00:00'
SET @TimeOnly = '01 jan 1899 10:11:23'
-- Gives Date Only.
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @DateOnly))
-- Gives Time Only.
SELECT DATEADD(Day, -DATEDIFF(Day, 0, @TimeOnly), @TimeOnly)
-- Concatenates Date and Time parts.
SELECT
CAST(
DATEADD(dd, 0, DATEDIFF(dd, 0, @DateOnly)) + ' ' +
DATEADD(Day, -DATEDIFF(Day, 0, @TimeOnly), @TimeOnly)
as datetime)
它很粗糙并且准备好了,但它确实有效!
【讨论】:
【参考方案6】:如果您的两个字段都是日期时间,那么只需添加它们即可。
例如:
Declare @d datetime, @t datetime
set @d = '2009-03-12 00:00:00.000';
set @t = '1899-12-30 12:30:00.000';
select @d + @t
如果您使用日期和时间数据类型,那么只需将时间转换为日期时间
例如:
Declare @d date, @t time
set @d = '2009-03-12';
set @t = '12:30:00.000';
select @d + cast(@t as datetime)
【讨论】:
【参考方案7】:将存储在 datetime 字段中的第一个日期转换为字符串,然后将存储在 datetime 字段中的时间转换为字符串,附加两者并转换回 datetime 字段,所有这些都使用已知的转换格式。
Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103)
【讨论】:
转换为字符串比 dateadd 慢。 ***.com/questions/2775/…【参考方案8】:将两个字段都转换为 DATETIME :
SELECT CAST(@DateField as DATETIME) + CAST(@TimeField AS DATETIME)
如果您使用的是Getdate()
,请先使用:
DECLARE @FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(@FechaActual as DATETIME) + CAST(@HoraInicioTurno AS DATETIME)
【讨论】:
【参考方案9】:如上所述,我有很多错误,所以我这样做了
try_parse(concat(convert(date,Arrival_date),' ',arrival_time) as datetime) AS ArrivalDateTime
它对我有用。
【讨论】:
【参考方案10】:这是我的解决方案,它忽略了时间列的日期值
CAST(Tbl.date as DATETIME) + CAST(CAST(Tbl.TimeFrom AS TIME) as DATETIME)
希望这对其他人有所帮助
【讨论】:
【参考方案11】:DECLARE @Dates table ([Date] datetime);
DECLARE @Times table ([Time] datetime);
INSERT INTO @Dates VALUES('2009-03-12 00:00:00.000');
INSERT INTO @Dates VALUES('2009-03-26 00:00:00.000');
INSERT INTO @Dates VALUES('2009-03-30 00:00:00.000');
INSERT INTO @Times VALUES('1899-12-30 12:30:00.000');
INSERT INTO @Times VALUES('1899-12-30 10:00:00.000');
INSERT INTO @Times VALUES('1899-12-30 10:00:00.000');
WITH Dates (ID, [Date])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Date]), [Date] FROM @Dates
), Times (ID, [Time])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Time]), [Time] FROM @Times
)
SELECT Dates.[Date] + Times.[Time] FROM Dates
JOIN Times ON Times.ID = Dates.ID
打印:
2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
【讨论】:
【参考方案12】:要将日期时间列中的日期和另一个日期时间列中的时间结合起来,这是最适合您的最快解决方案:
select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
【讨论】:
导致错误“数据类型 datetime 和 time 在 add 运算符中不兼容。” 参数为日期时间 过去的爆炸,哈哈,我看到你在我评论后修改了一段时间,很好:)【参考方案13】:SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table
像魅力一样工作
【讨论】:
导致错误“数据类型 date 和 datetime 在 add 运算符中不兼容。” SQL Server 2019(版本 15)【参考方案14】:选择 CAST(CAST(@DateField As Date) As DateTime) + CAST(CAST(@TimeField As Time) As DateTime)
【讨论】:
【参考方案15】:另一种方法是使用CONCAT
和CAST
,请注意,您需要使用DATETIME2(x)
才能使其工作。您可以将 x
设置为介于 0-7
7
之间的任何值,这意味着没有精度损失。
DECLARE @date date = '2018-03-12'
DECLARE @time time = '07:00:00.0000000'
SELECT CAST(CONCAT(@date, ' ', @time) AS DATETIME2(7))
返回2018-03-12 07:00:00.0000000
在 SQL Server 14 上测试
【讨论】:
【参考方案16】:只需将两者连接起来,但先将它们投射如下
select cast(concat(Cast(DateField as varchar), ' ', Cast(TimeField as varchar)) as datetime) as DateWithTime from TableName;
【讨论】:
【参考方案17】:发现这适用于两个日期,您希望从一个日期开始,从另一个日期开始:
declare @Time as datetime = '2021-11-19 12:34'
declare @Date as datetime = '2021-10-10'
SELECT @time + datediff(day, @Time, @Date)
【讨论】:
【参考方案18】:select s.SalesID from SalesTbl s
where cast(cast(s.SaleDate as date) as datetime) + cast(cast(s.SaleCreatedDate as time) as datetime) between @FromDate and @ToDate
【讨论】:
【参考方案19】:我遇到了类似的情况,我必须将日期和时间字段合并到日期时间字段。上述解决方案均不起作用,特别是添加两个字段,因为添加这两个字段的数据类型不一样。
我创建了下面的解决方案,我在日期中添加了小时和分钟部分。这对我来说效果很好。请检查一下,如果您遇到任何问题,请告诉我。
;与 tbl 作为 ( 选择 StatusTime = '12/30/1899 5:17:00 PM',StatusDate = '7/24/2019 12:00:00 AM' ) 选择 DATEADD(MI, DATEPART(MINUTE,CAST(tbl.StatusTime AS TIME)),DATEADD(HH, DATEPART(HOUR,CAST(tbl.StatusTime AS TIME)), CAST(tbl.StatusDate as DATETIME))) 来自tbl
结果:2019-07-24 17:17:00.000
【讨论】:
以上是关于如何将一个字段中的日期与另一字段中的时间结合起来 - MS SQL Server的主要内容,如果未能解决你的问题,请参考以下文章