SQL игнорирует наносекунды при сравнении datetime2
У меня есть 2 таблицы с полем datetime2
в каждой. Одна из таблиц также хранит наносекунды, в то время как другая хранит только до миллисекунд (нет никакого способа изменить эти данные). Теперь я хочу сравнить 2 таблицы и проверить, совпадают ли значения datetime2
, но для этого я должен игнорировать наносекунды.
Примерные данные:
Table1 Table2
2018-01-24 10:51:23.9976180 2018-01-24 10:51:23.9970000
2018-01-24 10:51:23.9976180 2018-01-24 10:51:23.9970000
2018-01-24 11:08:23.2578500 2018-01-24 11:08:23.2570000
Мой запрос в настоящее время выглядит следующим образом:
select t1.* from Table1 t1, Table12 t2 where t1.tradeDateTime = t2.tradeDate
Как вы можете догадаться, я не получаю никаких результатов для этого примера, потому что наносекунды отличаться.
Итак, мой вопрос заключается в том, как я могу игнорировать наносекунды в предложенииwhere
-?
Правка:
Я знаю, что должен использовать правильные JOIN
s. этот запрос был просто для проверки, не сделал ли я ошибок в своем запросе, используя JOIN
4 ответа:
Все зависит от того, с какой точностью вы хотите работать. Вы хотите сопоставить только часть даты или дату и время без миллисекунд?
Вот несколько способов изменить точность данных:CREATE TABLE #dates ( val DATETIME2 ); INSERT INTO #dates ( val ) VALUES ( SYSDATETIME()); INSERT INTO #dates ( val ) VALUES ( SYSDATETIME()); INSERT INTO #dates ( val ) VALUES ( SYSDATETIME()); SELECT d.val AsOriginalValue , CAST(d.val AS DATETIME) AsDateTime , CAST(d.val AS DATETIME2(0)) AsDateTime2_0 , CAST(d.val AS DATE) AsDate FROM #dates AS d; DROP TABLE #dates;
Приводит к:
Примечание: остерегайтесь округления.AsOriginalValue AsDateTime AsDateTime2_0 AsDate --------------------------- ----------------------- ---------------------- ---------- 2018-01-25 14:35:14.3660549 2018-01-25 14:35:14.367 2018-01-25 14:35:14 2018-01-25 2018-01-25 14:35:14.3665552 2018-01-25 14:35:14.367 2018-01-25 14:35:14 2018-01-25 2018-01-25 14:35:14.3670555 2018-01-25 14:35:14.367 2018-01-25 14:35:14 2018-01-25
Попробуйте привести к DATETIME
select t1.* from Table1 t1, Table12 t2 where CAST(t1.tradeDateTime as DATETIME) = CAST(t2.tradeDate as DATETIME)
Испытание
DECLARE @1 DATETIME2='2018-01-24 10:51:23.9976180' , @2 DATETIME2 = '2018-01-24 10:51:23.9970000' SELECT @1, @2, Test =CASE WHEN CAST(@1 AS DATETIME) = CAST(@2 AS DATETIME) THEN 1 ELSE 0 END
Приведите даты как
DateTime
, так как это приведет к приведению значения только к 3 десятичным знакам. Также, пожалуйста, используйте proberJOINS
:SELECT t1.* FROM Table1 t1 JOIN Table12 t2 ON t2.Joinable_ID = t1.Joinable_ID WHERE CAST(t1.tradeDateTime AS DATETIME) = CAST(t2.tradeDate AS DATETIME)
Использование функций в предложении
WHERE
может вызвать проблемы с производительностью. Вы можете получить лучшую скорость с подходом CTE:with t1 as (select cast(tradeDateTime as datetime) as tradeDateTimeNoTime from Table1) , t2 as (select cast(tradeDate as datetime) as tradeDateNoTime from Table2) select t1.* , t2.* from t1 inner join t2 on t1.tradeDateTimeNoTime = t2.tradeDateNoTime
Какое бы решение вы ни использовали, я определенно рекомендую использовать явный синтаксис
JOIN
, а не синтаксис запятой. Наконец, обратите внимание, что объединение в поле datetime не идеально для начала, поэтому вы можете рассмотреть подход, который использует идентификаторы в обеих таблицах.