2012-05-11 3 views
2

Я пытаюсь получить первый и последний день предыдущего месяца. Мне действительно нужен диапазон для предложения BETWEEN, поэтому мне нужна первая секунда первого дня и последняя секунда последнего дня.Каков самый простой и эффективный способ получить первую и последнюю дату предыдущего месяца?

Это код, который я использую:

set @startDate = DATEADD(mm, DATEDIFF(mm,0,DATEADD(mm, -1, getdate())), 0) 
set @endDate = dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate() ), 0)) 

Однако, на сегодняшний день, это на самом деле возвращение 4/1/2011 и 5/1/2011, которая не является абсолютно точным. Я хочу получить последнюю секунду от 30.04.2011 для endDate.

Я работаю в Интернете и вижу много разных способов получить первый/последний день месяца. Даже на самом SO, я вижу много разных вариантов этого вопроса с множеством разных ответов. Я хотел бы скомпилировать список всех методов для достижения этого, а затем определить, какой из них «лучший» (на основе простоты и эффективности)

(Должен добавить, что я использую SQL Server 2000)

EDIT:

Re в ENDDATE ошибка - этот код на самом деле правильно, проблема была только что @endDate был smalldatetime. Я изменил его на дату-время, и теперь он работает правильно.

+0

Re: The Edit. Это пример того, как использование '> = AND <' уменьшает объем ошибок, ошибок, сложностей и т. Д. – MatBailie

ответ

4

Для сроков я настоятельно рекомендую не использовать BETWEEN. Это подчеркивается необходимостью удалить 3 мс с даты, чтобы получить «последний момент предыдущего дня».

С непрерывными значениями (а не дискретными значениями), которые могут иметь разную степень точности, обычно лучше использовать >= AND <. Например ...

WHERE myDateField >= '2012-04-01' AND myDateField < '2012-05-01' 

Делая это, вы никогда не должны даже думать о точности данных myDateField или типа данных. Это просто работает. Всегда.


Имея это в виду, что ваш код очень близок к тому, что я хотел бы использовать ...

SET @start = DATEADD(month, DATEDIFF(month, 0, getDate()) - 1, 0) 
SET @end = DATEADD(month, DATEDIFF(month, 0, getDate()) , 0) 
+0

спасибо, я вижу вашу точку зрения ... Это определенно более точно, хотя «между» является чище (или просто wordier :)) указание того, что я пытаюсь сделать. Но я думаю, что точность козырей: :) Если я в конечном итоге использую этот код, я приму ответ – froadie

+0

@froadie - я согласен, что 'BETWEEN' чувствует себя как более чистый код. И он идеально подходит для дискретного значения (например, «BETWEEN 0 и 9').К сожалению, он просто не работает так хорошо с непрерывными значениями; вы вынуждены делать * приближение * конечного граничного условия. (Кто бы сделал «МЕЖДУ 0 И 9.99999» например?) – MatBailie

0

EDIT: в соответствии с разъяснениями от @Dems (см комментарии)

Я думаю, что теперь мой ответ будет таким же, как @Dems, мы оба имеем одинаковые ответы. :) @Dems Кредит идет к вам.

попробуйте этот запрос, он предоставит вам подходящие даты в соответствии с вашими потребностями.

select DATEADD(mm, DATEDIFF(mm,0,DATEADD(mm, -1, GETDATE())), 0) 
select DATEADD(mm, DATEDIFF(mm,0,GETDATE() ), 0) 

и использовать эту дату можно непосредственно использовать >= and < согласно предложению по @Dems ниже.

+0

Примечание: Это последний день месяца, но в 00:00 00 утра. OP использует '-3ms', чтобы получить последний« момент »этого дня. – MatBailie

+0

Да, я сделал это с целью, используя метод '> = AND <=', чтобы найти данные, с которыми будет легко управлять, только с датами. – Murtaza

+0

Я не предлагаю '> = AND <='. Я предлагаю '> = AND <'. Это позволяет избежать вычитания 1 дня, 3 мс или что-то еще. – MatBailie

Смежные вопросы