4

ある範囲の日付 (開始日と終了日) に 17 歳だったユーザーを選択します--

みんな、ありがとう!

ユーザー

  • ID
  • 生年月日

例:

  1. User_1 生年月日1996/09/28

  2. User_2 生年月日1996 年 8 月 25 日

  3. User_3 生年月日1995/07/28

  4. User_4 生年月日1995/05/25

日付の範囲がFROM 03/05/2013からEnd Date 6/05/2013の場合 *User_1 と User_2 は、その期間中に 17 歳であるという基準を満たすため表示されます*

でも

範囲がFrom 02/10/2012To End Date 06/05/2013の場合 、すべてのユーザーは、日付範囲内のある時点で 17 歳だったので表示されます。

Datepart() を使用してみましたが、必要な答えを導き出すためにそれを明確に考えることができません

Select u.id, u.birthdate
From Users u
where convert(varchar,DATEPART(MM,u.birthdate))<=DATEPART(MM,'03/05/2013')

みんなの助けを借りて、私は結論に達しました

DATEADD(YY,17,birthdate) between @from and @end
4

3 に答える 3

4

これらはそれを行う必要があります。

SELECT * FROM users 
WHERE birthdate BETWEEN DATEADD(year, -18, '2013-03-05')   -- lo date of range
                    AND DATEADD(year, -17, '2013-06-05');  -- hi date of range

SELECT * FROM users 
WHERE birthdate BETWEEN DATEADD(year, -18, '2012-02-10')   -- lo date of range
                    AND DATEADD(year, -17, '2013-06-05');  -- hi date of range

でテストする SQLfiddle

User_1 は 2013 年 9 月 28 日に 17 歳になり、User_2 は 2013 年 8 月 25 日に 17 歳になることに注意してください。

于 2013-06-05T19:35:29.817 に答える
2

私の好みの方法:

日付データ型と日付間の明示的な比較を使用します。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 など、ミリ秒まで)。

インデックス作成の可能性に注目してくれたすべての人に感謝します。「うまくいく、うまくいく、速くなる」という一連の流れを忘れないようにしましょう。

于 2013-06-05T19:43:16.437 に答える
-1

試す

SELECT * 
FROM
Users
WHERE
        DATEDIFF(year,@DATE1, '02/10/2012') = 17
OR
    DATEDIFF(year,@DATE2, '06/05/2013') =17

上記の @DATE1 と @DATE2 を必要な日付に置き換えます。

于 2013-06-05T18:41:11.520 に答える