2013-06-05 63 views
4

選擇用戶誰是17在一個日期範圍(從日期和結束日期)之間的17 -誰的年齡SQL選擇用戶的日期範圍

謝謝大家!

用戶

  • ID
  • 生日

實施例:

  1. USER_1生日1996年9月28日

  2. User_2生日1996年8月25日

  3. User_3生日1995年7月28日

  4. User_4生日1995年5月25日

如果日期範圍是從2013年3月5日結束日期2013年6月5日 * USER_1和User_2出現,因爲它們在該時間段內滿足的是17標準*

無論其

如果範圍是從02年/ 10/2012完結之日,因爲他們所有日期的範圍內,在某些時候是17 2013年6月5日 所有用戶應該出現

我一直在使用的日期部分()試過,但我不能明確地認爲它通過在答案得出我想

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 
+0

的序列您可以嘗試計算17歲生日發生的時間,如'DATEADD(年,+ 17,BirthDate)'。 –

+0

順便說一句,'User_1'在'2013-09-28'(1996 + 17)上僅用了17年,所以在2013-03-05和2013-06-05 –

回答

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 

An SQLfiddle to test with

注意USER_1上2013年9月28日和User_2上2013年8月25日變成17,因此它們都不是(或應是)包括在任一範圍。

+1

+1。 。 。這是最好的解決方案。在日期常數上進行日期運算比在「出生日期」列上進行算術要好 - 因爲「出生日期」的索引可以用於查詢。 –

+0

謝謝..我剛剛得出這個結論。我有DateAdd(YY,17,birthdadte)from – user196830

+0

我相信''之間'將包括18歲生日的用戶。我已經更新了我的答案,以解釋這個可能不正確的結果 –

-1

嘗試

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

更換@ DATE1和@ DATE2上述與所需的日期。

+0

之間不會出現問題。它只顯示在這兩個日期是17的用戶。那麼在 – user196830

+0

之間是17的用戶呢?確切地說,不要使用DATEDIFF。 –

2

我的首選方法:

使用日期數據類型和日期之間明確的比較。我建議在SQL Server 2008+中將birthdate存儲爲日期數據類型,並且還可以使用datetime文字的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歲之間通常有important difference)。我想你可以使用額外的DATEADD來減去一天,但我喜歡在我的使用BETWEEN作爲Aaron Bertrand suggests是一致的。

不要做什麼:

不要使用DATEPARTDATEDIFF這種類型的比較。他們不代表時間跨度。 DATEDIFF顯示跨越的差異。看到短短一天的以下年齡會顯示有人爲一歲已經,因爲這些年來在技術上是一個相距:

select datediff(year, '2012-12-31', '2013-01-01'); -- Returns 1! 

以這種方式使用「DATEPART」多年的計算會產生同樣的事情(類似於月/ 12等,一直到毫秒)。

感謝所有注意到索引可能性的人。讓我們不要忘記"Make it work, make it right, make it fast."

+0

如果您將DATEADD切換到2013-03-15/2013-06-05部分,您甚至可以使用出生日期的索引(如果有的話)? – Kevin

+0

@凱文,絕對。我已經更新了我的答案以反映這一點和其他想法。 –