如何将一个字段中的日期与另一字段中的时间结合起来 - 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 类型的编辑

DateTimeSQL 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@ 和 timedatetime2 更精确。【参考方案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】:

另一种方法是使用CONCATCAST,请注意,您需要使用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的主要内容,如果未能解决你的问题,请参考以下文章

获取一个字段的唯一记录,并与另一个字段的顺序结合

AWK/BASH:如何将一个文件中的字段与另一个文件中的字段匹配?

比较 MongoDB 中的两个日期字段

将三行与另一表中的一行连接起来

将日历上的日期与另一个字段匹配

仅返回一列中的日期与另一列中的日期最接近的行?