SQL Server 2016: объедините DATETIME2 (3) с DATETIME - PullRequest
6 голосов
/ 21 мая 2019

Я получаю неожиданные результаты при объединении столбцов DATETIME2(3) и DATETIME с PK в SQL Server 2016.

У меня есть следующая таблица:

CREATE TABLE DATETIME_TEST 
(
    [DATETIME] DATETIME NOT NULL,
    [DATETIME2_3] DATETIME2(3)
);

ALTER TABLE DATETIME_TEST 
    ADD CONSTRAINT PK_DATETIME_TEST PRIMARY KEY ([DATETIME]);

INSERT INTO DATETIME_TEST ([DATETIME], [DATETIME2_3])
VALUES ('20020202 02:02:02.000', '20020202 02:02:02.000'), 
       ('20020202 02:02:02.003', '20020202 02:02:02.003'), 
       ('20020202 02:02:02.007', '20020202 02:02:02.007'),
       ('2019-04-28 07:23:29.447', '2019-04-28 07:23:29.447');

SELECT * 
FROM DATETIME_TEST 
WHERE CONVERT(DATETIME2(3), [DATETIME]) = [DATETIME2_3]

Результаты:

DATETIME                  DATETIME2_3
-------------------------------------------------
2002-02-02 02:02:02.000   2002-02-02 02:02:02.000
2002-02-02 02:02:02.003   2002-02-02 02:02:02.003
2002-02-02 02:02:02.007   2002-02-02 02:02:02.007
2019-04-28 07:23:29.447   2019-04-28 07:23:29.447

Как вы можете видеть выше, значения равны.

SELECT      
    a.DATETIME,
    a.DATETIME2_3
FROM
    DATETIME_TEST a
INNER JOIN 
    DATETIME_TEST b ON CONVERT(DATETIME2(3), a.[DATETIME]) = b.[DATETIME2_3]

Результаты:

DATETIME2_3                  DATETIME
-----------------------------------------------------
2002-02-02 02:02:02.000      2002-02-02 02:02:02.000

Хотя значения равныЯ только некоторые строки.

Но если я удаляю PK или изменяю уровень совместимости на COMPATIBILITY_LEVEL = 120, тогда я получаю все строки, как и ожидалось

Это ошибка?

Есть ли лучший способ сделать это объединение.

Примечание. Я присоединяюсь к одной и той же таблице только для простоты примера из реальной жизни. Я соединяю две разные таблицы.

1 Ответ

0 голосов
/ 15 июня 2019

На самом деле, я тоже сталкивался с этим.Это определенно актуальный вопрос для Microsoft SQL Server Team.Спасибо, что нашли время на исправление этой ошибки.

Но в качестве альтернативного решения вы должны попытаться преобразовать тип данных «более богатый» (DATETIME2) в тип данных «более бедный» (DATETIME) в качестве метода обратной совместимости.,И тогда он даст вам результаты, которые вы ищете:

SELECT      
    a.DATETIME,
    a.DATETIME2_3
FROM
    DATETIME_TEST a
INNER JOIN 
    DATETIME_TEST b ON a.[DATETIME] = CONVERT(DATETIME, b.[DATETIME2_3])
...