2015-07-29 2 views
0

Как говорится в заголовке, у меня есть данные таблицы дат окончания контракта, и мне нужно вернуть список всех строк, где конечная дата находится между 15 и 20 дней. У меня есть следующий код:SQL-запрос, как вернуть все записи дат между 15 и 20 днями позже

WHERE (DATEDIFF([day], Contract.EndDate, GETDATE()) < 20) 
AND (Contract.EndDate < DATEADD([day], 15, GETDATE())) 
+2

'DATEDIFF ([day], Contract.EndDate, GETDATE()) от 15 до 20' –

ответ

2

Ваш запрос будет возвращать строки, в которых contract.endate менее чем за 20 дней с этого момента. Попробуйте это where пункт

DATEDIFF([day], Contract.EndDate, GETDATE()) between 15 and 20 
2

Это гораздо лучше написано как:

WHERE Contract.EndDate >= DATEADD(DAY, 15, GETDATE()) 
AND  Contract.EndDate < DATEADD(DAY, 21, GETDATE()) 

NB Я предположил, что вы хотите включить вещи с 20-й день, поэтому добавили 21 дней к GETDATE(), если это неверное предположение, а затем просто измените его на 20

Выполнение этого способа означает, что две константы (15 и 21 день вперед) вычисляются один раз во время выполнения, тогда никакие другие функции не являются используется, в то время как если вы используете что-то вроде:

DATEDIFF([day], Contract.EndDate, GETDATE()) < 20 

Вы должны выполнять функцию DATEDIFF на каждой строке, это означает, что любой индекс, который существует на Contract.EndDate не может быть использован (предикат не sargable). Даже если индекс не существует, несмотря на то, что он очень мало накладных расходов, функция DATEDIFF все еще имеет небольшой бит, поэтому зачем выполнять функцию сотни, тысячи, а может быть, миллионы раз, когда этого будет достаточно.

Это также в основном личные предпочтения, потому что до тех пор, как вы понимаете, что BETWEEN делает запросы могут быть написаны правильно, но я всегда использовать с открытым концом диапазона при работе с датами (т.е. DATE >= X AND DATE < Y). Это намного яснее (ИМО) и гораздо реже приводит к неожиданным результатам. Aaron Bertrand написал очень хорошую статью на эту тему - What do BETWEEN and the devil have in common?

Для чего это стоит, проблема с вашим запросом ваши два пункта оба с указанием даты менее чем на определенную дату:

WHERE (DATEDIFF([day], Contract.EndDate, GETDATE()) < 20) 

Это ограничит к строкам, где «EndDate» менее чем за 20 дней в будущем, что желательно поведение, а следующий пункт

AND  (Contract.EndDate < DATEADD([day], 15, GETDATE())) 

ограничат строки туда, где «EndDate» менее чем за 15 дней в будущем, что нежелательно r, < в этом втором предикате должно быть >.

Использование сегодня в качестве примера вы, по сути есть где положение, что государства

WHERE Contract.EndDate < '2015-08-18' 
AND  Contract.EndDate < '2015-08-13' 

Таким образом, вы имеете право верхний предел, но это также будет возвращать все строки в прошлом.

+0

Что именно должно работать здесь? Потому что это не так. – supersteve

+0

В самом начале, где предложение должно работать: 'WHERE Contract.EndDate> = DATEADD (DAY, 15, GETDATE()) AND Contract.EndDate GarethD

+0

Я извиняюсь, это работает. Должно быть, было что-то не так. Большое спасибо за Вашу помощь! – supersteve