Cara menggabungkan tanggal dari satu bidang dengan waktu dari bidang lain - MS SQL Server

198

Dalam ekstrak yang saya hadapi, saya memiliki 2 datetimekolom. Satu kolom menyimpan tanggal dan waktu lainnya seperti yang ditunjukkan.

Bagaimana saya bisa meminta tabel untuk menggabungkan dua bidang ini menjadi 1 kolom tipe datetime?

tanggal

2009-03-12 00:00:00.000
2009-03-26 00:00:00.000
2009-03-26 00:00:00.000

Waktu

1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
Jon Winstanley
sumber

Jawaban:

253

Anda bisa menambahkan keduanya.

  • jika yang Time partanda Datekolom selalu nol
  • dan yang Date partanda Timekolom juga selalu nol (tanggal dasar: 1 Januari 1900)

Menambahkannya mengembalikan hasil yang benar.

SELECT Combined = MyDate + MyTime FROM MyTable

Rationale (pujian untuk ErikE / dnolan)

Ini berfungsi seperti ini karena cara tanggal disimpan sebagai dua 4-byte Integersdengan 4-byte kiri menjadi datedan 4-byte kanan adalah time. Ini seperti melakukan$0001 0000 + $0000 0001 = $0001 0001

Edit tentang tipe SQL Server 2008 baru

Datedan Timemerupakan tipe yang diperkenalkan di SQL Server 2008. Jika Anda bersikeras menambahkan, Anda dapat menggunakanCombined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

Edit2 tentang kehilangan presisi di SQL Server 2008 dan lebih tinggi (pujian untuk Martin Smith)

Lihat Bagaimana cara menggabungkan tanggal dan waktu ke datetime2 di SQL Server? untuk mencegah hilangnya presisi menggunakan SQL Server 2008 dan lebih tinggi.

Letnan Keersmaekers
sumber
2
@ Jon, Memang benar asalkan elemen waktu dari kolom tanggal dan elemen tanggal dari kolom waktu sama-sama nol.
LukeH
1
Anda kemungkinan besar mengalami apa yang dideskripsikan di sini groups.google.be/group/... borland * + penulis% 3A teamb * # 1ab62659d8be3135
Lieven Keersmaekers
2
Tanggal "nol" dalam SQL Server adalah 1900-01-01, bukan?
Andriy M
1
Ketika saya mencoba ini saya tidak perlu membuang nilai 'waktu' ke datetime. Dengan kata lain yang dapat Anda lakukan: datetime + time
Sam
1
Tanggal @dnolan di SQL server TIDAK disimpan sebagai float. Di mana di bumi Anda belajar ini? Mereka disimpan sebagai bilangan bulat : bagian tanggal adalah jumlah hari sejak tanggal jangkar, dan bagian waktu adalah jumlah "kutu" sejak tengah malam, kutu didefinisikan sebagai 1/300 s untuk datetimedan lebih tepat untuk timedan datetime2.
ErikE
129

Jika elemen waktu kolom tanggal Anda dan elemen tanggal kolom waktu Anda sama-sama nol, maka jawaban Lieven adalah yang Anda butuhkan. Jika Anda tidak dapat menjamin bahwa itu akan selalu menjadi masalah, maka itu menjadi sedikit lebih rumit:

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
LukeH
sumber
Terima kasih atas jawabannya Luke. Untungnya, dalam hal ini saya bisa menjamin barang-barang lain selalu nol, saya pikir 2 bidang bahkan mungkin 1 di sisi lain kode pihak ke-3 yang melakukan ekstrak untuk kita.
Jon Winstanley
6
Saya memiliki masalah yang sama dengan OP kecuali saya tahu bagian yang tidak dibutuhkan tidak pernah nol. Karena itu, ini sangat berguna, jika saya dapat memilih Anda dua kali, saya akan!
Ini menyelamatkan saya! Saya mengubah keduanya menjadi karakter dan kemudian menyimpulkan dan kemudian kembali ke DATETIME, tapi kemudian saya tidak bisa mengindeksnya, karena SQL mengatakan itu tidak menentukan. Ini rupanya deterministik !!! TERIMA KASIH !!! KAMU !!!
eidylon
4
Versi SQL Server 2008 Anda tidak berfungsi. The data types datetime and time are incompatible in the add operator.
Martin Smith
@ Martin: Saya telah menghapus versi SQL2008 yang rusak.
LukeH
26

Ini adalah solusi alternatif tanpa konversi karakter:

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

Anda hanya akan mendapatkan akurasi milidetik dengan cara ini, tetapi itu biasanya tidak masalah. Saya telah menguji ini di SQL Server 2008.

Jojje
sumber
14

Ini berhasil untuk saya

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

(pada SQL 2008 R2)

biso
sumber
1
Bekerja dengan baik di SQL Server 2008.
Tobias
7
Saya mendapatkan Tipe data datetime dan waktu tidak kompatibel di add operator. kesalahan pada SQL Server 2012
Devin Prejean
4
SQL 2012 Tipe data datetime dan waktu tidak kompatibel di add operator
Raffaeu
3
Ini tidak lagi berfungsi di SQL Server 2012 dan di atasnya (melanggar perubahan). Lihat di sini untuk perincian: social.msdn.microsoft.com/forums/azure/en-US/…
Heinzi
10

Jika Anda tidak menggunakan SQL Server 2008 (yaitu Anda hanya memiliki tipe data DateTime), Anda dapat menggunakan TSQL berikut ini (memang kasar dan siap) untuk mencapai apa yang Anda inginkan:

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)

Ini kasar dan siap, tetapi berhasil!

CraigTP
sumber
9
  1. Jika kedua bidang Anda adalah datetime maka cukup menambahkannya akan berhasil.

    misalnya:

    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. Jika Anda menggunakan tipe data Tanggal & Waktu maka cukup masukkan waktu ke datetime

    misalnya:

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

Ubah tanggal pertama yang disimpan dalam bidang datetime menjadi string, lalu konversikan waktu yang disimpan dalam bidang datetime menjadi string, tambahkan keduanya dan konversi kembali ke bidang datetime semua menggunakan format konversi yang diketahui.

Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103) 
SPE109
sumber
3
Konversi ke string lebih lambat dari dateadd. stackoverflow.com/questions/2775/…
ErikE
2

Saya memiliki banyak kesalahan seperti yang dinyatakan di atas sehingga saya melakukannya seperti ini

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

Ini berhasil untuk saya.

Tom
sumber
2

Konversikan kedua bidang menjadi DATETIME:

SELECT CAST(@DateField as DATETIME) + CAST(@TimeField AS DATETIME)

dan jika Anda menggunakan Getdate()gunakan ini dulu:

DECLARE @FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(@FechaActual as DATETIME) + CAST(@HoraInicioTurno AS DATETIME)
Alex Briones
sumber
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

Cetakan:

2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
Konstantin Tarkus
sumber
1
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table

Bekerja seperti pesona

Kristian Radolovic
sumber
0

SELECT CAST (CAST (@DateField As Date) Sebagai DateTime) + CAST (CAST (@TimeField As Time) Sebagai DateTime)

Shah
sumber
0

Cara lain adalah menggunakan CONCATdan CAST, perlu diketahui, bahwa Anda perlu menggunakannya DATETIME2(x)untuk membuatnya bekerja. Anda dapat mengatur xapa saja di antara yang 0-7 7berarti tidak ada kehilangan presisi.

DECLARE @date date = '2018-03-12'
DECLARE @time time = '07:00:00.0000000'
SELECT CAST(CONCAT(@date, ' ', @time) AS DATETIME2(7))

Kembali 2018-03-12 07:00:00.0000000

Diuji pada SQL Server 14

LuckyLikey
sumber
-1

Untuk menggabungkan tanggal dari kolom datetime dan waktu dari kolom datetime lain, ini adalah solusi tercepat untuk Anda:

select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
Wael Galal El Deen
sumber
Hasil dalam kesalahan "Tipe data datetime dan waktu tidak kompatibel di operator tambah."
Oskar Berggren
-1

Saya mengalami situasi yang sama di mana saya harus menggabungkan bidang Tanggal dan Waktu ke bidang DateTime. Tak satu pun dari solusi yang disebutkan di atas bekerja, khususnya menambahkan dua bidang sebagai tipe data untuk penambahan 2 bidang ini tidak sama.

Saya membuat solusi di bawah ini, di mana saya menambahkan bagian jam dan kemudian menit ke tanggal. Ini bekerja dengan baik untuk saya. Silakan periksa dan beri tahu saya jika Anda mengalami masalah.

; dengan tbl sebagai (pilih StatusTime = '12 / 30/1899 5:17:00 PM ', StatusDate =' 7/24/2019 12:00:00 AM ') pilih DATEADD (MI, DATEPART (MENIT, CAST (tbl .StatusTime SEBAGAI WAKTU)), DATEADD (HH, DATEPART (JAM, CAST (tbl.StatusTime SEBAGAI WAKTU)), CAST (tbl.StatusDate as DATETIME))) dari tbl

Hasil: 2019-07-24 17: 17: 00.000

rahul shinde
sumber