31

Using SQL Server 2008, this query works great:

select CAST(CollectionDate as DATE), CAST(CollectionTime as TIME)
from field

Gives me two columns like this:

2013-01-25  18:53:00.0000000
2013-01-25  18:53:00.0000000
2013-01-25  18:53:00.0000000
2013-01-25  18:53:00.0000000
    .
    .
    .

I'm trying to combine them into a single datetime using the plus sign, like this:

select CAST(CollectionDate as DATE) + CAST(CollectionTime as TIME)
from field

I've looked on about ten web sites, including answers on this site (like this one), and they all seem to agree that the plus sign should work but I get the error:

Msg 8117, Level 16, State 1, Line 1
Operand data type date is invalid for add operator.

All fields are non-zero and non-null. I've also tried the CONVERT function and tried to cast these results as varchars, same problem. This can't be as hard as I'm making it.

Can somebody tell me why this doesn't work? Thanks for any help.

4

12 に答える 12

58

基になるデータ型が日付/時刻/日時型であると仮定します。

SELECT CONVERT(DATETIME, CONVERT(CHAR(8), CollectionDate, 112) 
  + ' ' + CONVERT(CHAR(8), CollectionTime, 108))
  FROM dbo.whatever;

これにより、CollectionDateandCollectionTimeが char シーケンスに変換され、結合されてから、 に変換されますdatetime

へのパラメーターCONVERTdata_typeexpressionおよびオプションですstyle(構文のドキュメントを参照してください)。

日付と時刻styleの値112は ISOyyyymmdd形式に変換されます。style値がフォーマットに108変換されhh:mi:ssます。どちらも 8 文字の長さであることは明らかdata_typeですCHAR(8)

結果として結合された char シーケンスは 形式yyyymmdd hh:mi:ssであり、 に変換されdatetimeます。

于 2013-09-04T19:47:19.113 に答える
10

より簡単なソリューション (SQL Server 2014 SP1 CU6 でテスト済み)

コード:

DECLARE @Date date = SYSDATETIME();

DECLARE @Time time(0) = SYSDATETIME();

SELECT CAST(CONCAT(@Date, ' ', @Time) AS datetime2(0));

これは、特定の日付と特定の時間フィールドを持つテーブルでも機能します。2 つの別々のフィールドで日付と時刻を使用するベンダー データがある場合、私はこの方法を頻繁に使用します。

于 2016-06-08T19:32:09.230 に答える
8

代わりにキャストしdatetimeます:

select CAST(CollectionDate as DATETIME) + CAST(CollectionTime as TIME)
from field

これは、SQL Server 2008 R2 で機能します。

なんらかの理由で、最初の部分に時間コンポーネントがないことを確認したい場合は、最初にフィールドを date にキャストしてから、 に戻しdatetimeます。

于 2013-09-04T19:47:50.570 に答える
2

解決策 (1): 日時演算

DATE としてキャストできる任意の @myDate と、TIME としてキャストできる任意の @myTime を指定すると、SQL Server 2014+ を起動すると、これは正常に機能し、文字列操作は必要ありません。

CAST(CAST(@myDate as DATE) AS DATETIME) + CAST(CAST(@myTime as TIME) as DATETIME)

次の方法で確認できます。

SELECT  GETDATE(), 
        CAST(CAST(GETDATE() as DATE) AS DATETIME) + CAST(CAST(GETDATE() as TIME) as DATETIME)

解決策 (2): 文字列操作

SELECT  GETDATE(), 
        CONVERT(DATETIME, CONVERT(CHAR(8), GETDATE(), 112) + ' ' + CONVERT(CHAR(8), GETDATE(), 108))

ただし、ソリューション (1) はソリューション (2) よりも 2 ~ 3 倍高速であるだけでなく、マイクロ秒の部分も維持されます。

ソリューション (1) の日付演算とソリューション (2) を使用した文字列操作については、SQL Fiddle を参照してください。

于 2020-01-26T19:01:05.820 に答える
0

これは SQL 2008 および 2012 で機能し、datetime2 を生成します。

declare @date date = current_timestamp;
declare @time time = current_timestamp;

select 
@date as date
,@time as time
,cast(@date as datetime) + cast(@time as datetime) as datetime
,cast(@time as datetime2) as timeAsDateTime2
,dateadd(dayofyear,datepart(dayofyear,@date) - 1,dateadd(year,datepart(year,@date) - 1900,cast(@time as datetime2))) as datetime2;
于 2014-02-20T00:40:41.260 に答える
0
drop table test

create table test(
    CollectionDate date NULL,
    CollectionTime  [time](0) NULL,
    CollectionDateTime as (isnull(convert(datetime,CollectionDate)+convert(datetime,CollectionTime),CollectionDate))
-- if CollectionDate is datetime no need to convert it above
)

insert test (CollectionDate, CollectionTime)
values ('2013-12-10', '22:51:19.227'),
       ('2013-12-10', null),
       (null, '22:51:19.227')

select * from test

CollectionDate  CollectionTime  CollectionDateTime
2013-12-10      22:51:19        2013-12-10 22:51:19.000
2013-12-10      NULL            2013-12-10 00:00:00.000
NULL            22:51:19        NULL
于 2013-12-11T11:07:08.853 に答える