2011-12-14 15 views
2

私は簡潔に多くの場所で発見されない古いコードベースのビットで働いています。私たちは常にデータベースで使用しているコードのこれらの2つのSQLコードは同じですか?

ワンピース2つの日付が同じプログラム年度内にあるかどうかを決定することです。たとえば、2011年度は2011年7月1日から2012年7月1日に終了します(または技術的には前日)

この問題を解決する通常の方法は、次の種類のコードを使用することです。

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))' 

私はこのことについてお伺いしたいと思います。これらの2つのコードはまったく同じですか?彼らはいつも同じ出力を出すでしょうか(有効な日付を仮定して)?

答えて

1

私が見る問題は、あなたがそれに対して操作をやっているので、元の溶液を希望しながら、オプティマイザによっては、あなたのソリューションは、(それが良く見える)、ENROLLMENTDATE上で定義されたインデックスを使用しないかもしれない、ということです。そのフィールドにインデックスがない場合は、問題は発生しません。

+0

+1 ...まだ後者の形式は同じですが、それがある場合でも、(すべてであれば)、有効EnrollmentDateにインデックスを使用することができなくなりますように深刻なパフォーマンスヒットを得るために起こっている確信していません。 –

0

12月は31日ですので、何ヶ月も減算する必要はありません。日付範囲は1年であるため、元の日付がいつでもいつでも真となります。一般的なケースでは、他の日付から始まる登録年度です。この状況に対処するためにも、簡単な方法で作成することです

WHERE enrolmentdate >= @YearBeg(:enrolmentdate + 6 MONTHS) - 6 MONTHS 
    AND enrolmentdate < @YearBeg(:enrolmentdate + 6 MONTHS) + 6 MONTHS 
1

私はかつて、文字列いじるよりも、これは少し簡単になり、日付操作関数の範囲で、このようなものをSQLの方言を使用しましたプログラム年度の列を含むカレンダーテーブル。そして、まったく論理は、あなただけの値を照会し、それらを比較、ありません。

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

カレンダーのテーブルを作成し、多くの異なる目的のためにそれらを使用する方法について、このサイト上の多くの記事があります。私の経験では、このようにテーブルを使用することは、コード内に式を作成するよりも、常に明確で保守性が向上します。

関連する問題