SQL фильтрует конкретный месяц, день и время для любого года

Microsoft Dynamics NAV использует datetime из yyyy-12-31 23:59:59.000 для определения записей закрытия года. Пытаюсь написать отчет, в который приведу все мои записи, кроме этих. Запрос отлично работает для 2014, если я явно использую предложение WHERE из

WHERE [Posting Date] <> '2014-12-31 23:59:59.000')

Но мне нужно, чтобы запрос работал для любого года. Я старался:

WHERE (DATEPART(mm, [Posting Date]) <> 12) AND 
      (DATEPART(dd, [Posting Date]) <> 31) AND 
      (DATEPART(hh, [Posting Date]) <> 23) AND 
      (DATEPART(mi, [Posting Date]) <> 59) AND 
      (DATEPART(ss, [Posting Date]) <> 59)

Но это отфильтровало все, что было в December или имело день 31 или час 23 и т. д.

Есть ли простой способ отфильтровать заданную дату и время, но с любым годом?


person Boone    schedule 29.05.2015    source источник


Ответы (2)


Может быть, это:

WHERE MONTH([Posting Date]) <> 12 OR
      DAY([Posting Date]) <> 31 OR
      CAST([Posting Date] AS TIME) <> CAST('23:59:59.000' AS TIME)

Еще более короткий ответ:

WHERE YEAR([Posting Date]) <> YEAR(DATEADD(ss, 1, [Posting Date]))
person Giorgi Nakeuri    schedule 29.05.2015
comment
К сожалению, я получаю те же результаты, что и мой неработающий запрос. - person Boone; 29.05.2015
comment
@Boone, да была ошибка, тебе нужно ORs - person Giorgi Nakeuri; 29.05.2015
comment
Я подозреваю, что производительность для этого будет очень плохой, поскольку оптимизатор запросов не сможет использовать какие-либо индексы и должен будет обрабатывать каждую строку. Лучшей идеей было бы создать таблицу с датами исключения на следующие 50 лет (только 50 строк) и исключить их из отчета, например, с помощью `ГДЕ [Дата публикации] НЕ В...) - person Panagiotis Kanavos; 29.05.2015
comment
@PanagiotisKanavos, спасибо за этот совет. Хотя мои данные относительно малы, их было очень просто реализовать, и время выполнения сократилось с 11 до 8 секунд. - person Boone; 29.05.2015

Еще одна вещь, которую вы также можете сделать, это что-то вроде этого, что является небольшим отличием от того, что вы пробовали.

WHERE 1 = CASE 
        WHEN (
                DATEPART(MONTH, [POSTING DATE]) = 12
                AND DATEPART(DAY, [POSTING DATE]) = 31
                AND DATEPART(HOUR, [POSTING DATE]) = 23
                AND DATEPART(MINUTE, [POSTING DATE]) = 59
                AND DATEPART(SECOND, [POSTING DATE]) = 59
                )
            THEN 0
        ELSE 1
        END

В этом сценарии я просто использую CASE для идентификации тех строк, которые имеют дату в последнюю секунду года, а оценка 1/0 делает все остальное и отфильтровывает ненужные записи.

person Radu Gheorghiu    schedule 29.05.2015