Bir alandaki tarih ile başka bir alandaki saat nasıl birleştirilir - MS SQL Server


200

Karşılaştığım bir alıntıda 2 datetimesütunum var. Bir sütun tarihleri ​​gösterildiği gibi, diğeri de gösterildiği gibi saklar.

Bu iki alanı 1 tür sütunda birleştirmek için tabloyu nasıl sorgulayabilirim datetime?

Tarih

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

Zamanlar

1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000

Yanıtlar:


254

Sadece ikisini ekleyebilirsiniz.

  • eğerTime part listenizdekilerdenDate sütuna her zaman sıfırdır
  • veDate part senin içinde Timesütununda da her zaman sıfırdır (baz tarih: 1900 1 Ocak)

Bunları eklemek doğru sonucu döndürür.

SELECT Combined = MyDate + MyTime FROM MyTable

Gerekçe (Kudos a ErikE / dnolan)

Tarihin 4 4 bayt olarak depolanması Integersve sol 4 baytın datesağ ve 4 baytın sağ olması gibi çalışır time. Yapmak gibi$0001 0000 + $0000 0001 = $0001 0001

Yeni SQL Server 2008 türleriyle ilgili düzenleme

Dateve Timetanıtılan türlerdir SQL Server 2008. Eklemekte ısrar ederseniz, şunu kullanabilirsiniz:Combined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

SQL Server 2008 ve sonraki sürümlerde hassasiyet kaybı ile ilgili Edit2

SQL Server'da tarih ve saati datetime2 ile nasıl birleştirebilirsiniz? SQL Server 2008 ve üzerini kullanarak hassasiyet kaybını önlemek için.


2
@Jon, Tarih sütununun zaman öğesi ve zaman sütununun tarih öğesinin her ikisi de sıfır olduğu sürece doğrudur.
LukeH

1
Büyük olasılıkla burada anlatılanları yaşıyor olabilirsiniz groups.google.be/group/… borland * + yazar% 3A teamb * # 1ab62659d8be3135
Lieven Keersmaekers

2
SQL Server'da "sıfır" tarihi 1900-01-01, değil mi?
Andriy M

1
Bunu denediğimde 'zaman' değerini datetime döküm gerek yoktu. Başka bir deyişle: datetime + time
Sam

1
SQL sunucusunda @dnolan tarihleri ​​olarak saklanmaz float. Bunu nereden öğrendin? Onlar olarak depolanır tamsayılar : tarih bölümü bir çapa tarihten itibaren gün sayısı ve zaman bölümü gece yarısından itibaren "kene" sayısını olduğunu için 1/300 sn olarak tanımlanan keneler datetimeve daha hassas timeve datetime2.
ErikE

130

Tarih sütununuzun zaman öğesi ve zaman sütununuzun tarih öğesi hem sıfırsa, Lieven'nin cevabı ihtiyacınız olan şeydir. Her zaman böyle olacağını garanti edemezseniz, biraz daha karmaşık hale gelir:

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

Cevabınız için teşekkürler Luke. Neyse ki, bu durumda diğer öğelerin her zaman sıfır olduğunu garanti edebilirim, 2 alanın diğer tarafta 1 bile olabileceğini düşünüyorum.
Jon Winstanley

6
OP ile aynı sorunu yaşadım, ancak gereksiz parçaların asla sıfır olmadığını biliyorum. Bu yüzden bu ölçülemeyecek kadar faydalı oldu, eğer size iki kez oy verebilirsem!

Bu beni kurtardı! Ben hem chars dönüştürmek ve sonra concating ve sonra DATETIME için geri, ama sonra ben dizin olamazdı, çünkü SQL deterministic olmadığını söyledi. Bu görünüşte belirleyicidir! TEŞEKKÜR !!! SEN !!!
eidylon

4
SQL Server 2008 sürümünüz çalışmıyor. The data types datetime and time are incompatible in the add operator.
Martin Smith

@Martin: Bozuk SQL2008 sürümünü kaldırdım.
LukeH

26

Bu, herhangi bir char dönüşümü olmayan alternatif bir çözümdür:

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

Bu şekilde yalnızca milisaniye doğruluk elde edersiniz, ancak normalde sorun olmaz. Bunu SQL Server 2008'de test ettim.


14

Bu benim için çalıştı

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

(SQL 2008 R2'de)


1
SQL Server 2008'de harika çalıştı.
Tobias

7
Veri türü tarih ve saat veri ekleme işleci ile uyumsuz. Server 2012'de hata
Devin Prejean

4
SQL 2012 tarih ve saat veri türleri, ekleme işleci ile uyumlu değil
Raffaeu

3
Bu artık SQL Server 2012 ve sonraki sürümlerinde çalışmaz (değişikliği bozma). Ayrıntılar için buraya bakın: social.msdn.microsoft.com/forums/azure/en-US/…
Heinzi

10

SQL Server 2008 kullanmıyorsanız (yani yalnızca bir DateTime veri türünüz varsa), istediğinizi elde etmek için aşağıdaki (kuşkusuz kaba ve hazır) TSQL'i kullanabilirsiniz:

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)

Kaba ve hazır, ama işe yarıyor!


9
  1. Her iki alanınız datetime ise, yalnızca bu alanları eklemek işe yarayacaktır.

    Örneğin:

    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. Tarih ve Saat veri türünü kullandıysanız, sadece tarih için zaman verin

    Örneğin:

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

3

Tarih saat alanında depolanan ilk tarihi bir dizeye dönüştürün, sonra datetime alanında depolanan zamanı dizeye dönüştürün, ikisini ekleyin ve tümünü bilinen dönüştürme biçimlerini kullanarak bir tarih saat alanına dönüştürün.

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

3
Dizeye dönüştürmek dateadd'den daha yavaş. stackoverflow.com/questions/2775/…
ErikE

2

Yukarıda belirtildiği gibi birçok hatayla karşılaştım, bu yüzden böyle yaptım

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

Benim için çalıştı.


2

Her iki alanı da DATETIME biçimine dönüştür:

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

ve kullanıyorsanız Getdate()önce bunu kullanın:

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

Baskılar:

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

1
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table

Tıkır tıkır çalışıyor


0

CAST (CAST (Tarih olarak @TateField) SEAT) + CAST (CAST (Tarih olarak @TimeField))


0

Bir başka yolu kullanmaktır CONCATve CASTkullanmak gerektiğini, farkında, DATETIME2(x)o iş yapmak. Hassasiyet kaybı yok anlamına gelen herhangi bir xşeye ayarlayabilirsiniz 0-7 7.

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

İadeler 2018-03-12 07:00:00.0000000

SQL Server 14 üzerinde test edildi


0

her ikisini de birleştirin, ancak önce aşağıdaki gibi yayınlayın

select cast(concat(Cast(DateField as varchar), ' ', Cast(TimeField as varchar)) as datetime) as DateWithTime from TableName;

-1

Tarih / saat sütunundaki tarihi ve başka bir tarih / saat sütunundaki saati birleştirmek için bu sizin için en hızlı çözümdür:

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

"Tarih ve saat veri türleri, ekleme işleci ile uyumsuz."
Oskar Berggren

-1

Tarih ve Saat alanlarını DateTime alanıyla birleştirmek zorunda kaldığım benzer bir durumla karşılaştım. Yukarıda belirtilen çözümlerin hiçbiri, özellikle bu iki alanın eklenmesine ilişkin veri türü olarak iki alan eklemek için aynı değildir.

Aşağıdaki çözümü oluşturdum, burada tarihe saat ve dakika parçası ekledim. Bu benim için güzel çalıştı. Lütfen kontrol edin ve herhangi bir sorunla karşılaşırsanız bana bildirin.

; tbl ile (StatusTime = '12 / 30/1899 17:17:00 'seçin, StatusDate =' 7/24/2019 12:00:00 ') DATEADD (MI, DATEPART (MINUTE, CAST (tbl) .SATusTime AS TIME), DATEADD (HH, DATEPART (HOUR, CAST (tbl.StatusTime AS TIME)), CAST (tbl.StatusDate DATETIME olarak)))

Sonuç: 2019-07-24 17: 17: 00.000

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.