Являются ли эти две части кода SQL одинаковыми? - PullRequest
2 голосов
/ 15 декабря 2011

Я работаю с более старой базой кода, где краткость не найдена во многих местах.

Один фрагмент кода, который мы постоянно используем в базе данных, заключается в определении того, находятся ли две даты в одном программном году. Например, программный год 2011 начинается 1 июля 2011 года и заканчивается 1 июля 2012 года (или технически днем ​​ранее)

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

if Month(@EnrollmentDate)>=7 begin
  set @StartDate='07/01/'+LTRIM(RTRIM(Year(@EnrollmentDate)))
  set @EndDate='07/01/'+LTRIM(RTRIM(Year(@EnrollmentDate)+1))
end else begin
  set @StartDate='07/01/'+LTRIM(RTRIM(Year(@EnrollmentDate)-1))
  set @EndDate='07/01/'+LTRIM(RTRIM(Year(@EnrollmentDate)))
end
...
where (ENROLLMENTDATE >= @StartDate and ENROLLMENTDATE < @EndDate)

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

where year(dateadd(mm,-6,ENROLLMENTDATE)) = year(dateadd(mm,-6,@EnrollmentDate))'

Прежде чем я начну вносить новые ошибки в систему, которая "просто работает", я бы хотел спросить об этом SO. Являются ли эти две части кода одинаковыми? Будут ли они всегда давать один и тот же результат (при условии правильной даты)?

Ответы [ 3 ]

1 голос
/ 15 декабря 2011

Еще более простой способ справиться с этой ситуацией - создать таблицу календаря со столбцом для программного года. Тогда нет никакой логики, вы просто запрашиваете значения и сравниваете их:

if 
(select ProgramYear from dbo.Calendar where BaseDate = @StartDate) = 
(select ProgramYear from dbo.Calendar where BaseDate = @EndDate)
begin
-- do something
end

На этом сайте много постов о создании календарных таблиц и их использовании для различных целей. По моему опыту, использование таблицы таким способом всегда понятнее и удобнее, чем создание формул в коде.

1 голос
/ 15 декабря 2011

проблема, которую я вижу, состоит в том, что в зависимости от оптимизатора ваше решение (которое выглядит лучше) может не использовать индекс, определенный для ENROLLMENTDATE, поскольку вы выполняете над ним операции, в то время как исходное решение будет. Если в этом поле нет индексов, я не вижу проблемы

0 голосов
/ 15 декабря 2011

Как оказалось, в декабре 31 день, поэтому независимо от того, сколько месяцев вам нужно вычесть, вы всегда сможете выровнять итоговый диапазон дат по целому году, и, следовательно, ваше выражение всегда будет истинным всякий раз, когда оригиналВо-первых, даже в общем случае для года регистрации, начинающегося с других дат.

Однажды я использовал диалект SQL с рядом функций манипулирования датами, которые сделали это немного проще, чем перестановка строк, что-то вроде этого:

WHERE enrolmentdate >= @YearBeg(:enrolmentdate + 6 MONTHS) - 6 MONTHS
  AND enrolmentdate < @YearBeg(:enrolmentdate + 6 MONTHS) + 6 MONTHS
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...