如何将一个字段中的日期与另一个字段中的时间结合在一起-MS SQL Server


198

在我正在处理的摘录中,我有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

Answers:


252

您可以简单地将两者相加。

  • 如果Time part你的Date列始终为零
  • 并且Date part你的Time栏也始终为零(基准日: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类型

DateTime是在中引入的类型SQL Server 2008。如果您坚持添加,可以使用Combined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

有关SQL Server 2008及更高版本中的精度损失的Edit2(对Martin Smith表示感谢)

看看如何在SQL Server中将日期和时间结合到datetime2?以防止使用SQL Server 2008及更高版本的精度损失。


2
@Jon,这是真的,只要date列的时间元素和time列的日期元素都为零。
2009年

1
您最有可能遇到此处描述的问题groups.google.be/group/…borland * + author%3A teamb *#1ab62659d8be3135
Lieven Keersmaekers 2010年

2
SQL Server中的“零”日期是1900-01-01,不是吗?
Andriy M

1
当我尝试这样做时,我不需要将“时间”值转换为日期时间。换句话说,您可以执行以下操作:datetime + time
Sam Sam'7

1
SQL Server中的@dnolan日期不存储为float。您在哪里在哪里学习的?它们被存储为整数:日期部分是因为锚定日期的天数,和时间部分是因为午夜“滴答”的次数,蜱被定义为1/300 S表示datetime和更精确的timedatetime2
ErikE

129

如果您的日期栏的时间要素你的时间列的日期元素均为零,然后利芬的答案是你所需要的。如果您不能保证始终如此,那么情况会变得稍微复杂一些:

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

感谢您的回答卢克。幸运的是,在这种情况下,我可以保证其他项始终为零,我认为在为我们提取内容的第三方代码的另一端,这两个字段甚至可能为1。
乔恩·温斯坦利

6
除了我知道不需要的部分永远不会为零之外,我和OP都有同样的问题。因此,如果我能两次投票赞成您,这将是非常有用的!

这救了我!我将它们都转换为char,然后进行转换,然后又转换为DATETIME,但是后来我无法对其进行索引,因为SQL表示这是不确定的。这显然是确定性的!!!谢谢 !!!你!!!
eidylon'3

4
您的SQL Server 2008版本不起作用。The data types datetime and time are incompatible in the add operator.
马丁·史密斯

@Martin:我已经删除了损坏的SQL2008版本。
路加

26

这是没有任何字符转换的替代解决方案:

DATEADD(ms, DATEDIFF(ms, '00:00:00', [Time]), CONVERT(DATETIME, [Date]))

这样您将只能获得毫秒级的精度,但这通常是可以的。我已经在SQL Server 2008中对此进行了测试。


14

这对我有用

CAST(Tbl.date as DATETIME) + CAST(Tbl.TimeFrom AS TIME)

(在SQL 2008 R2上)


1
在SQL Server伟大的工作2008年
托比亚斯

7
我得到数据类型datetime和time在add运算符中不兼容。SQL Server 2012上的错误
Devin Prejean

4
SQL 2012数据类型datetime和time在add运算符中不兼容
Raffaeu

3
这在SQL Server 2012及更高版本中不再起作用(重大更改)。详情请参阅此处:social.msdn.microsoft.com/forums/azure/zh-CN/…–
Heinzi

10

如果您不使用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)

它很粗糙,已经准备好了,但是可以用!


9
  1. 如果您的两个字段均为日期时间,则只需将其添加即可。

    例如:

    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
    
  2. 如果您使用日期和时间数据类型,则只需将时间转换为日期时间

    例如:

    Declare @d date, @t time
    set @d = '2009-03-12';
    set @t = '12:30:00.000';
    select @d + cast(@t as datetime)
    

3

将存储在datetime字段中的第一个日期转换为字符串,然后将存储在datetime字段中的时间转换为字符串,将两者附加在一起,并使用已知的转换格式转换回datetime字段。

Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103) 

3
转换为字符串比dateadd慢。stackoverflow.com/questions/2775/...
ErikE

2

如上所述,我有很多错误,所以我做到了

try_parse(concat(convert(date,Arrival_date),' ',arrival_time) as datetime) AS ArrivalDateTime

它为我工作。


2

将两个字段都转换为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)

1
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


0

选择CAST(CAST(@DateField作为日期)作为DateTime)+ CAST(CAST(@TimeField作为时间)作为DateTime)


0

另一种方法是使用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上测试


-1

要将日期时间列中的日期与另一个日期时间列中的时间结合起来,这是最快速的解决方案:

select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable

导致错误“添加操作符中的数据类型datetime和time不兼容”。
Oskar Berggren

-1

我遇到了类似的情况,我不得不将日期和时间字段合并到DateTime字段。上述解决方案均无效,特别是添加两个字段作为添加这两个字段的数据类型是不相同的。

我创建了以下解决方案,在其中添加了小时,然后是分钟。这对我来说效果很好。请检查出来,如果遇到任何问题,请告诉我。

;使用tbl as(select 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)),tbl的DATEADD(HH,DATEPART(HOUR,CAST(tbl.StatusTime AS TIME)),CAST(tbl.StatusDate as DATETIME))))

结果:2019-07-24 17:17:00.000

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.