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 -?

Правка:

Я знаю, что должен использовать правильные JOINs. этот запрос был просто для проверки, не сделал ли я ошибок в своем запросе, используя JOIN

4 4

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 десятичным знакам. Также, пожалуйста, используйте prober JOINS:

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 не идеально для начала, поэтому вы можете рассмотреть подход, который использует идентификаторы в обеих таблицах.