私の好みの方法:
日付データ型と日付間の明示的な比較を使用します。SQL Server 2008 以降では生年月日を日付データ型として保存し、あいまいさを避けるために日時リテラルにISO 8601形式を使用することをお勧めします。
select id, birthdate
from Users
where birthdate > dateadd(year, -18, '2013-03-05') -- Check lower bounds
and birthdate <= dateadd(year, -17, '2013-06-05'); -- Check upper bounds
dateaddこのリビジョンでは、関数を定数に移動したことに注意してください。他の人が鋭く観察したように、これは計算が少なくなることを意味し (行が 1 行しかない場合を除きますか?)、おそらくもっと重要なことに、生年月日のインデックスを使用できるようになります。
BETWEENメソッド:
別の回答に示されているように、を使用BETWEENすると同様の結果が得られます。
select id, birthdate
from users
where birthdate between dateadd(year, -18, '2013-03-05')
and dateadd(year, -17, '2013-06-05')
ただし、包括的です。つまり、終点を含むBETWEENすべての範囲で一致します。この場合、任意のユーザーの 18 歳の誕生日に一致が得られますが、これは望ましい結果ではない可能性が高くなります (多くの場合、 17 歳と 18 歳の間には重要な違いがあります)。足し算を使って1 日を引くこともできると思いますが、アーロン バートランドが示唆するように、私の使い方は一貫したものにしたいと思っています。DATEADDBETWEEN
してはいけないこと:
このタイプの比較にはDATEPARTorを使用しないでください。DATEDIFFそれらはタイムスパンを表すものではありません。 交差した境界DATEDIFFの点で違いを示します。技術的には年が 1 年離れているため、次の 1 日だけの年齢が、すでに 1 歳であることを示していることを確認してください。
select datediff(year, '2012-12-31', '2013-01-01'); -- Returns 1!
この方法で「DATEPART」を使用して年を計算すると、同じ結果が得られます (同様に、月/12 など、ミリ秒まで)。
インデックス作成の可能性に注目してくれたすべての人に感謝します。「うまくいく、うまくいく、速くなる」という一連の流れを忘れないようにしましょう。