Як поєднати дату з одного поля з часом з іншого поля - 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

Відповіді:


252

Ви можете просто додати два.

  • якщоTime part ваша Dateколонка завжди дорівнює нулю
  • іDate part вашої Timeколонки також завжди дорівнює нулю (базова дата 1 січня 1900)

Додавання їх повертає правильний результат.

SELECT Combined = MyDate + MyTime FROM MyTable

Обгрунтування (кудо ErikE / dnolan)

Це працює так через те, що дата зберігається як два 4-байтових, Integersпричому лівий 4- байтний, dateа правий 4- байтний time. Це як робити$0001 0000 + $0000 0001 = $0001 0001

Редагувати щодо нових типів SQL Server 2008

Dateі Timeце типи, введені в SQL Server 2008. Якщо ви наполягаєте на додаванні, можете використовуватиCombined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)

Edit2 щодо втрати точності в SQL Server 2008 і новіших версіях (кудо Мартіну Сміту)

Подивіться, як поєднувати дату та час з timetime2 у SQL Server? щоб запобігти втраті точності за допомогою SQL Server 2008 і новіших версій.


2
@Jon, це правда, якщо елемент часу стовпця дати та елемент дати стовпця часу дорівнюють нулю.
ЛукаH

1
Ви, швидше за все, відчуваєте те, що тут описано groups.google.be/group/… borland * + author% 3A teamb * # 1ab62659d8be3135
Lieven Keersmaekers

2
"Нульова" дата в SQL Server - це так 1900-01-01, ні?
Андрій М

1
Коли я це спробував, мені не потрібно було привласнювати значення 'time' дату timetime. Іншими словами, ви можете зробити: datetime + time
Sam

1
Дати @dnolan на SQL-сервері НЕ зберігаються як float. Де на землі ви цього дізналися? Вони зберігаються у вигляді цілих чисел : частина дати - це кількість днів з дати прив’язки, а часова частина - кількість "кліщів" з півночі, тики визначаються як 1/300 с для datetimeі більш точні для timeта datetime2.
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

Дякую за відповідь Лука. На щастя, в цьому випадку я можу гарантувати, що інші елементи завжди дорівнюють нулю, я думаю, що 2 поля можуть бути навіть 1 з іншого боку, стороннім кодом, який робить витяг для нас.
Джон Вінстанлі,

6
У мене була така ж проблема, як у ОП, за винятком того, що я знаю, що зайві деталі ніколи не дорівнюють нулю. Тому це було незмірно корисно, якби я міг би проголосувати за вас двічі, я би!

Це мене врятувало! Я перетворював обидва знаки на знаки, а потім концентрував, а потім повертався до DATETIME, але тоді я не міг його індексувати, оскільки SQL сказав, що це не детерміновано. Це, очевидно, детерміновано !!! СПАСИБІ !!! ТИ !!!
ейдилон

4
Ваша версія SQL Server 2008 не працює. The data types datetime and time are incompatible in the add operator.
Мартін Сміт

@Martin: Я видалив зламану версію SQL2008.
ЛукаХ

26

Це альтернативне рішення без будь-яких перетворень char:

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.
Tobias

7
Я отримую Типи даних дата та час несумісні в операторі додавання. помилка на SQL Server 2012
Devin Prejean

4
SQL 2012 Типи даних дата та час несумісні в операторі додавання
Raffaeu,

3
Це більше не працює в SQL Server 2012 і вище (порушення змін). Детальніше дивіться тут: social.msdn.microsoft.com/forums/azure/en-US/…
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

Перетворіть першу дату, що зберігається в полі дати, у рядок, потім перетворіть час, збережений у полі дати, у рядок, додайте їх і перетворіть назад у поле дати, використовуючи відомі формати перетворення.

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

3
Перетворення в рядок відбувається повільніше, ніж додано дату. 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

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


0

Інший спосіб - це використовувати CONCATі CAST, будьте в курсі, що вам потрібно використовувати 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

Результати помилки "Типи даних дата та час несумісні в операторі додавання."
Оскар Берггрен

-1

Я зіткнувся з подібною ситуацією, коли мені довелося об'єднати поля Дата і Час у поле DateTime. Жодне з вищезгаданих рішень не працює, спеціально додаючи два поля, оскільки тип даних для додавання цих двох полів не є однаковим.

Я створив рішення нижче, де додав годинну, а потім і хвилинну частину дати. Це прекрасно працювало для мене. Будь ласка, перевірте це і повідомте мені, якщо ви стикаєтесь з будь-якими проблемами.

; з tbl як (виберіть StatusTime = '12 / 30/1899 17:17:00 ', StatusDate =' 24.07.2019 00: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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.