जन्मतिथि और गेट डेट () के आधार पर आयु (वर्षों में) की गणना कैसे करें


171

मेरे पास अपनी जन्मतिथि के साथ लोगों को सूचीबद्ध करने वाली एक तालिका है (वर्तमान में एक नवरचेर (25))

मैं इसे एक तिथि में कैसे बदल सकता हूं, और फिर वर्षों में उनकी आयु की गणना कर सकता हूं?

मेरा डेटा इस प्रकार दिखता है

ID    Name   DOB
1     John   1992-01-09 00:00:00
2     Sally  1959-05-20 00:00:00

मैं देखना चाहूँगा:

ID    Name   AGE  DOB
1     John   17   1992-01-09 00:00:00
2     Sally  50   1959-05-20 00:00:00

16
आप डेटाबेस की मूल तिथि या डेटाइम प्रकार का उपयोग करने के बजाय nvarchar (25) का उपयोग करके तार मान के रूप में दिनांक मान क्यों संग्रहीत कर रहे हैं?
जेसपर

इस प्रश्न को 2005 में टैग नहीं किया गया है 2008 इसलिए देशी 'तिथि' प्रकार उपलब्ध नहीं है, लेकिन निश्चित रूप से एक डेटाइम है, और यह लघुडॉटटाइम का तर्क दिया जा सकता है क्योंकि आपको सटीकता की आवश्यकता नहीं है।
एंड्रयू

नमस्ते, varchar के रूप में तारीख़ें रखने का कारण यह है क्योंकि मैं इसे एक गैर-SQL सर्वर स्कीमा से आयात कर रहा हूं, कुछ मुद्दे थे जो इन्हें डेटाइम (और दूसरी तारीख के प्रारूप) के रूप में आयात कर रहे थे और varchar ने ok को रूपांतरित कर दिया था
जिमी

7
@ James.Elsey, इसलिए आपके पास आयात करने के मुद्दे थे और परिणामस्वरूप सभी तिथियां मान्य हैं? जब तक आप एक डेटाइम या स्मालडैटाइम का उपयोग नहीं करते हैं, तब तक यह सुनिश्चित नहीं हो सकता है, कि आप varchar के साथ काम करने के लिए अपना आयात प्राप्त कर सकते हैं, लेकिन लाइन में अन्य समस्याएं हैं। इसके अलावा, मैं उम्र को कभी स्टोर नहीं करूंगा, यह हर दिन बदलता है, एक दृश्य
केएम का

@ केएम हाँ, उस डेटा को एक तारीख के रूप में आयात करने वाला एक मुद्दा था, उस समय एकमात्र व्यवहार्य समाधान उन्हें nvarchars के रूप में आयात करना था। यह चयन एक रात की नौकरी का हिस्सा बनने जा रहा है, इसलिए उम्र को संग्रहीत करना एक मुद्दा नहीं होना चाहिए
जिमी

जवाबों:


256

लीप वर्ष / दिन और निम्न विधि के साथ समस्याएँ हैं, नीचे अद्यतन देखें:

इसे इस्तेमाल करे:

DECLARE @dob  datetime
SET @dob='1992-01-09 00:00:00'

SELECT DATEDIFF(hour,@dob,GETDATE())/8766.0 AS AgeYearsDecimal
    ,CONVERT(int,ROUND(DATEDIFF(hour,@dob,GETDATE())/8766.0,0)) AS AgeYearsIntRound
    ,DATEDIFF(hour,@dob,GETDATE())/8766 AS AgeYearsIntTrunc

उत्पादन:

AgeYearsDecimal                         AgeYearsIntRound AgeYearsIntTrunc
--------------------------------------- ---------------- ----------------
17.767054                               18               17

(1 row(s) affected)

अपडेट करें यहाँ कुछ और सटीक तरीके हैं:

INT में साल के लिए सबसे अच्छा तरीका है

DECLARE @Now  datetime, @Dob datetime
SELECT   @Now='1990-05-05', @Dob='1980-05-05'  --results in 10
--SELECT @Now='1990-05-04', @Dob='1980-05-05'  --results in  9
--SELECT @Now='1989-05-06', @Dob='1980-05-05'  --results in  9
--SELECT @Now='1990-05-06', @Dob='1980-05-05'  --results in 10
--SELECT @Now='1990-12-06', @Dob='1980-05-05'  --results in 10
--SELECT @Now='1991-05-04', @Dob='1980-05-05'  --results in 10

SELECT
    (CONVERT(int,CONVERT(char(8),@Now,112))-CONVERT(char(8),@Dob,112))/10000 AS AgeIntYears

आप ऊपर बदल सकते हैं 10000 को10000.0 और दशमलव प्राप्त , लेकिन यह नीचे की विधि के समान सटीक नहीं होगा।

डेमलिम में साल के लिए सबसे अच्छा तरीका

DECLARE @Now  datetime, @Dob datetime
SELECT   @Now='1990-05-05', @Dob='1980-05-05' --results in 10.000000000000
--SELECT @Now='1990-05-04', @Dob='1980-05-05' --results in  9.997260273973
--SELECT @Now='1989-05-06', @Dob='1980-05-05' --results in  9.002739726027
--SELECT @Now='1990-05-06', @Dob='1980-05-05' --results in 10.002739726027
--SELECT @Now='1990-12-06', @Dob='1980-05-05' --results in 10.589041095890
--SELECT @Now='1991-05-04', @Dob='1980-05-05' --results in 10.997260273973

SELECT 1.0* DateDiff(yy,@Dob,@Now) 
    +CASE 
         WHEN @Now >= DATEFROMPARTS(DATEPART(yyyy,@Now),DATEPART(m,@Dob),DATEPART(d,@Dob)) THEN  --birthday has happened for the @now year, so add some portion onto the year difference
           (  1.0   --force automatic conversions from int to decimal
              * DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),DATEPART(m,@Dob),DATEPART(d,@Dob)),@Now) --number of days difference between the @Now year birthday and the @Now day
              / DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),1,1),DATEFROMPARTS(DATEPART(yyyy,@Now)+1,1,1)) --number of days in the @Now year
           )
         ELSE  --birthday has not been reached for the last year, so remove some portion of the year difference
           -1 --remove this fractional difference onto the age
           * (  -1.0   --force automatic conversions from int to decimal
                * DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),DATEPART(m,@Dob),DATEPART(d,@Dob)),@Now) --number of days difference between the @Now year birthday and the @Now day
                / DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),1,1),DATEFROMPARTS(DATEPART(yyyy,@Now)+1,1,1)) --number of days in the @Now year
             )
     END AS AgeYearsDecimal

24
यह भी एक सटीक समाधान नहीं है। अगर मैं अपने खुद के @dob को '1986-07-05 00:00:00' पर ले जाऊं और मैं इसे GETDATE()'2013-07-04 23:59:59' पर इसे (इसके बजाय दूसरे चर का उपयोग कर ) निष्पादित करूंगा, तो यह कहता है कि मैं 27 मई, जबकि उस समय, मैं अभी तक नहीं हूँ। उदाहरण कोड: declare @startDate nvarchar(100) = '1986-07-05 00:00:00' declare @endDate nvarchar(100) = '2013-07-04 23:59:59' SELECT DATEDIFF(hour,@startDate,@endDate)/8766.0 AS AgeYearsDecimal ,CONVERT(int,ROUND(DATEDIFF(hour,@startDate,@endDate)/8766.0,0)) AS AgeYearsIntRound ,DATEDIFF(hour,@startDate,@endDate)/8766 AS AgeYearsIntTrunc
bartlaarhoven

20
यह सही नहीं है क्योंकि यह प्रति वर्ष 8766 घंटे मानता है, जो 365.25 दिनों तक काम करता है। चूंकि 365.25 दिनों के साथ कोई वर्ष नहीं हैं, इसलिए यह सही होने की तुलना में अधिक बार व्यक्ति की जन्मतिथि के पास गलत होगा। यह विधि अभी भी अधिक सटीक है।
बेकन बिट्स

1
दूसरा @ बाकोन बिट्स टिप्पणी - यह अक्सर गलत होगा जब वर्तमान तिथि किसी व्यक्ति की जन्म तिथि के निकट हो।
फ़्लैश

2
मुझे लगता है कि पाठ का पहला ब्लॉक इस उत्तर को भ्रामक बनाता है। यदि आपके अपडेट किए गए तरीके में लीप वर्षों के साथ समस्या नहीं है, तो मैं आपको अपने उत्तर के निचले भाग को स्थानांतरित करने के लिए सुझाव दूंगा (यदि आप वास्तव में इसे बिल्कुल रखना चाहते हैं)।
अजेबवेन

1
यदि आप एक सटीक गणना चाहते हैं , तो DatedIFF यह @ShailendraMishra नहीं करेगा, क्योंकि यह दिनों का अनुमान लगाता है, आदि। उदाहरण के लिए, select datediff(year, '2000-01-05', '2018-01-04')18 को लौटाता है, 17 को नहीं जितना चाहिए। मैंने "BEST METHOD FOR YEARS IN INT" शीर्षक के तहत ऊपर के उदाहरण का उपयोग किया और यह पूरी तरह से काम करता है। धन्यवाद!
ओपनवॉन्क

132

यह एक वहाँ फेंक देना होगा। यदि आप दिनांक को 112 शैली (yyyymmdd) का उपयोग करके संख्या में परिवर्तित करते हैं, तो आप इस तरह की गणना का उपयोग कर सकते हैं ...

(yyyyMMdd - yyyyMMdd) / 10000 = पूरे वर्ष में अंतर

declare @as_of datetime, @bday datetime;
select @as_of = '2009/10/15', @bday = '1980/4/20'

select 
    Convert(Char(8),@as_of,112),
    Convert(Char(8),@bday,112),
    0 + Convert(Char(8),@as_of,112) - Convert(Char(8),@bday,112), 
    (0 + Convert(Char(8),@as_of,112) - Convert(Char(8),@bday,112)) / 10000

उत्पादन

20091015    19800420    290595  29

14
यह लगभग जादुई है कि यह सभी लीप वर्ष की समस्याओं को हल करता है। यह ध्यान देने योग्य है कि 112 CONVERT फ़ंक्शन के लिए एक विशेष संख्या है जो कि yyyymmdd के रूप में दिनांक को प्रारूपित करता है। जब आप इसे देखते हैं तो यह संभवतः सभी के लिए स्पष्ट नहीं होता है।
डेरेक टॉम्स २ '

5
आप एक प्रतिभाशाली हैं!
ercan

मेरी टीम एक ऐसे मुद्दे पर चल रही थी जब हम जिस तारीख को पाने के लिए उम्र का इस्तेमाल कर रहे थे, वह उसी दिन थी जिस दिन हम इसकी तुलना कर रहे थे। हम देख रहे थे कि जब वे एक ही दिन थे (और यदि उम्र विषम हो रही थी) तो उम्र एक से कम हो जाएगी। यह पूरी तरह से काम किया!
Sheek Geek

1
यह सही उत्तर है - कृपया इसे इस तरह चिह्नित करें।
Snympi

4
SQL सर्वर 2012 में इस सटीक समान गणना पद्धति के लिए सबसे सरल / सबसे छोटा कोड हैcode: SELECT [Age] = (0+ FORMAT(@as_of,'yyyyMMdd') - FORMAT(@bday,'yyyyMMdd') ) /10000 --The 0+ part tells SQL to calc the char(8) as numbers
ukgav

44

मैंने लगभग 10 वर्षों के लिए हमारे उत्पादन कोड में इस क्वेरी का उपयोग किया है:

SELECT FLOOR((CAST (GetDate() AS INTEGER) - CAST(Date_of_birth AS INTEGER)) / 365.25) AS Age

6
यह बुरा नहीं है, लेकिन 100% नहीं है, 2007/10/16 2009/10/15 को 2 साल की उम्र की रिपोर्ट करेगा
एंड्रयू

4
दोह, हम स्पष्ट याद कर रहे हैं, यह मध्याह्न के बाद है, गेटडैट एक इंट देता है ताकि निश्चित रूप से गोल हो जाएगा। मैं आपके उत्तर को कॉपी करता हूं और उसे चलाता हूं, इसलिए स्वचालित रूप से गेटडेट का उपयोग किया जाता है, न कि शाब्दिक रूप से।
एंड्रयू

2
सुरुचिपूर्ण और सरल। धन्यवाद!
विलियम एमबी

9
यदि हम मानव युगों के बारे में बात कर रहे हैं, तो आपको इसे मनुष्यों की गणना करने के तरीके की गणना करनी चाहिए। इसका इस बात से कोई लेना-देना नहीं है कि पृथ्वी कितनी तेजी से चलती है और कैलेंडर के साथ क्या करना है। हर बार उसी महीने और दिन को जन्म की तारीख के रूप में समाप्त हो जाता है, आप उम्र में वृद्धि करते हैं 1. इसका मतलब यह है कि निम्नलिखित सबसे सटीक है क्योंकि यह दर्पण है कि मनुष्यों का क्या मतलब है जब वे "आयु" कहते हैं:DATEDIFF(yy, @BirthDate, GETDATE()) - CASE WHEN (MONTH(@BirthDate) >= MONTH(GETDATE())) AND DAY(@BirthDate) > DAY(GETDATE()) THEN 1 ELSE 0 END
बेकन बिट्स

5
क्षमा करें, वह वाक्य रचना गलत है। CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END
बेकन बिट्स

31

उपरोक्त समाधानों में से कई गलत हैं DateDiff (yy, @ Dob, @PassedDate) दोनों तिथियों के महीने और दिन पर विचार नहीं करेंगे। इसके अलावा डार्ट भागों और तुलना केवल तभी काम करता है जब वे ठीक से ऑर्डर किए जाते हैं।

पूरी तरह से काम करता है और बहुत सरल है:

create function [dbo].[AgeAtDate](
    @DOB    datetime,
    @PassedDate datetime
)

returns int
with SCHEMABINDING
as
begin

declare @iMonthDayDob int
declare @iMonthDayPassedDate int


select @iMonthDayDob = CAST(datepart (mm,@DOB) * 100 + datepart  (dd,@DOB) AS int) 
select @iMonthDayPassedDate = CAST(datepart (mm,@PassedDate) * 100 + datepart  (dd,@PassedDate) AS int) 

return DateDiff(yy,@DOB, @PassedDate) 
- CASE WHEN @iMonthDayDob <= @iMonthDayPassedDate
  THEN 0 
  ELSE 1
  END

End

आप 100 से गुणा क्यों कर रहे हैं? यह मेरे लिए काम करता है जैसा कि मैं डेटाबेस में दोहराने के लिए कोशिश कर रहा हूं जो हमारे कोड लाइब्रेरी में मौजूद है - लेकिन मैं आपके फ़ंक्शन की व्याख्या नहीं कर सका। यह एक बेवकूफी भरा सवाल हो सकता है :)
जेन

6
धन्यवाद! वास्तव में कोड मैं यहाँ उम्मीद कर रहा था। यह (बदसूरत) स्ट्रिंग परिवर्तनों के बिना इस धागे में एकमात्र सही कोड है! @ जब यह DoB के महीने और दिन (25 सितंबर की तरह) लेता है और इसे पूर्णांक मान 0925(या 925) में बदल देता है । यह वर्तमान तिथि (जैसे दिसंबर 16 बन जाता है 1216) के साथ भी ऐसा ही करता है और फिर यह जांचता है कि क्या DoB पूर्णांक मान पहले ही पास हो चुका है। इस पूर्णांक बनाने के लिए, महीने 100 से गुणा किया जाना चाहिए
bartlaarhoven

धन्यवाद @bartlaarhoven :)
जेन

मैं सिर्फ यह उल्लेख करूंगा कि जब यह स्ट्रिंग परिवर्तन से बचता है, तो यह बहुत सी कास्टिंग करता है। मेरा परीक्षण दिखाता है कि यह डॉटजेओ के उत्तर की तुलना में बहुत तेज़ नहीं है , और कोड अधिक क्रिया है।
स्ट्रिपिंगवर्यर

स्वीकृत उत्तर में बहुत सरल INT उत्तर है:(CONVERT(int,CONVERT(char(8),@Now,112))-CONVERT(char(8),@Dob,112))/10000
KM।

19

आपको दिनांकित कमांड राउंड के तरीके पर विचार करने की आवश्यकता है।

SELECT CASE WHEN dateadd(year, datediff (year, DOB, getdate()), DOB) > getdate()
            THEN datediff(year, DOB, getdate()) - 1
            ELSE datediff(year, DOB, getdate())
       END as Age
FROM <table>

जिसे मैंने यहाँ से अनुकूलित किया

ध्यान दें कि यह 28 फरवरी को गैर-लीप वर्ष के लिए एक जन्मदिन के जन्मदिन के रूप में माना जाएगा। उदाहरण के लिए 29 फरवरी 2020 को पैदा हुए व्यक्ति को 01 मार्च 2021 के बजाय 28 फरवरी 2021 को 1 वर्ष का माना जाएगा।


@ और - सही - मैं प्रतिस्थापन में से एक को याद किया
एड हार्पर

1
सरलीकृत संस्करणSELECT DATEDIFF(year, DOB, getdate()) + CASE WHEN (DATEADD(year,DATEDIFF(year, DOB, getdate()) , DOB) > getdate()) THEN - 1 ELSE 0 END)
पीटर

यह सही तरीका है; मुझे समझ नहीं आ रहा है कि हैक्स को इतना क्यों उखाड़ा जाता है।
सलमान ए

8

संपादित करें: इस उत्तर का इतिहास है। मैं इसे dayofyearअंत में एक और संपादन के साथ उपयोग करने के लिए प्रलोभन के रूप में यहां छोड़ता हूं ।


अगर, मेरी तरह, आप भिन्नात्मक दिनों या जोखिम दौर / लीप ईयर त्रुटियों से विभाजित नहीं करना चाहते हैं, तो मैं https://stackoverflow.com/a/1572257/489465 से ऊपर एक पोस्ट में @Bacon बिट्स टिप्पणी की सराहना करता हूं जहां वह कहते हैं:

यदि हम मानव युगों के बारे में बात कर रहे हैं, तो आपको इसे मनुष्यों की आयु की गणना करने के तरीके की गणना करनी चाहिए। इसका इस बात से कोई लेना-देना नहीं है कि पृथ्वी कितनी तेजी से चलती है और कैलेंडर के साथ क्या करना है। हर बार एक ही महीने और दिन को जन्म की तारीख के रूप में समाप्त हो जाता है, आप उम्र 1 से बढ़ाते हैं। इसका मतलब यह है कि निम्नलिखित सबसे सटीक है क्योंकि यह दर्पण है कि मनुष्यों का क्या मतलब है जब वे "आयु" कहते हैं।

वह तो प्रदान करता है:

DATEDIFF(yy, @date, GETDATE()) -
CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE()))
THEN 1 ELSE 0 END

महीने और दिन की तुलना करने के लिए यहां कई सुझाव दिए गए हैं (और कुछ इसे गलत मानते हैं, ORयहां सही तरीके से अनुमति देने में विफल हैं!)। लेकिन किसी ने पेशकश नहीं की है dayofyear, जो इतना सरल और बहुत कम लगता है। में पेश करता हु:

DATEDIFF(year, @date, GETDATE()) -
CASE WHEN DATEPART(dayofyear, @date) > DATEPART(dayofyear, GETDATE()) THEN 1 ELSE 0 END

[नोट: SQL BOL / MSDN में कहीं भी नहीं है जो DATEPART(dayofyear, ...)वास्तव में प्रलेखित है! मैं इसे १-३६६ की सीमा में एक संख्या समझता हूँ; सबसे महत्वपूर्ण बात यह है नहीं के अनुसार क्षेत्र के अनुसार बदलने DATEPART(weekday, ...)और SET DATEFIRST।]


संपादित करें: क्यों dayofyearगलत हो जाता है : उपयोगकर्ता के रूप में @AeroX टिप्पणी की है, अगर जन्म / शुरू की तारीख एक गैर लीप वर्ष में फरवरी के बाद है, उम्र एक दिन जल्दी वृद्धि की जाती है जब वर्तमान / समाप्ति तिथि एक लीप वर्ष है, उदाहरण के लिए '2015-05-26', '2016-05-25'एक देता है 1 की उम्र जब यह अभी भी होनी चाहिए 0. dayofyearविभिन्न वर्षों में तुलना करना स्पष्ट रूप से खतरनाक है। तो सभी के बाद का उपयोग करना MONTH()और DAY()आवश्यक है।


यह वोट दिया जाना चाहिए या यहां तक ​​कि जवाब के रूप में चिह्नित किया जाना चाहिए। यह छोटा, सुरुचिपूर्ण और तार्किक रूप से सही है।
z00l

1
फरवरी के बाद पैदा होने वाले सभी लोगों के लिए DayOfYearविधि का उपयोग करके प्रत्येक लीप वर्ष में एक दिन पहले ही उम्र बढ़ाई जाती है ।
ऐरोक्स

4
@AeroX इस दोष को पहचानने के लिए धन्यवाद। मैंने अपने समाधान को चेतावनी के रूप में छोड़ने का फैसला किया जो किसी ने भी इस्तेमाल किया है या हो सकता है dayofyear, लेकिन स्पष्ट रूप से यह दिखाने के लिए संपादित किया गया कि यह गलत क्यों है। मुझे आशा है कि यह उपयुक्त है।
जॉनब्रा

5

चूंकि कोई एक सरल उत्तर नहीं है जो हमेशा सही उम्र देता है, यहाँ पर मैं क्या कर रहा हूँ।

SELECT DATEDIFF(YY, DateOfBirth, GETDATE()) - 
     CASE WHEN RIGHT(CONVERT(VARCHAR(6), GETDATE(), 12), 4) >= 
               RIGHT(CONVERT(VARCHAR(6), DateOfBirth, 12), 4) 
     THEN 0 ELSE 1 END AS AGE 

यह जन्म तिथि और वर्तमान तिथि के बीच वर्ष का अंतर है। यदि जन्मतिथि अभी तक पास नहीं हुई है तो यह एक साल घटा देता है।

हर समय सटीक - लीप वर्ष या जन्मतिथि के करीब होने की परवाह किए बिना।

सबसे अच्छा - कोई फ़ंक्शन नहीं।


3
SELECT ID,
Name,
DATEDIFF(yy,CONVERT(DATETIME, DOB),GETDATE()) AS AGE,
DOB
FROM MyTable

1
आप दूसरे तर्क के रूप में प्राप्त करना चाहते हैं क्योंकि पहले नहीं तो आपको नकारात्मक संख्या परिणाम मिलते हैं, और दिनांकित राउंड मिलते हैं, इसलिए दिनांकित का चयन करें (yy, '20081231', getdate ()) 1 वर्ष की आयु की रिपोर्ट करेगा, लेकिन वे केवल 10 महीने के होंगे ।
एंड्रयू

1
यह गणना उन लोगों के लिए गलत गणना है जो इस साल अभी तक उनका जन्मदिन नहीं है।

3

व्हाट अबाउट:

DECLARE @DOB datetime
SET @DOB='19851125'   
SELECT Datepart(yy,convert(date,GETDATE())-@DOB)-1900

कि उन सभी गोलाई, परेशान और परेशान मुद्दों से बचना नहीं होगा?


आप गणना सटीक नहीं है। उदाहरण के लिए: यदि आप '1986-07-05 00:00:00'DOB और '2013-07-04 23:59:59'वर्तमान समय के लिए लेते हैं तो यह विफल हो जाता है ।
11

@ub_coding क्या आप प्रस्ताव दे रहे हैं और जवाब दे रहे हैं या कोई अन्य प्रश्न पूछ रहे हैं?
हारून C

यह: DECLARE @DOB डेटाइम सेट @ DOB = '19760229' सिलेक्ट डेटपेंट (yy, Convert (डेटाइम, '19770228') - @ DOB) -1900 = 1 मुख्य समस्या अधिकांश समाधानों के लिए 29 गैप की है, जिसे ट्रंकिंग राउंडिंग आदि के बारे में बताया गया है। ।
लियोनार्डो मार्केस डी सूजा

3

मेरा मानना ​​है कि यह अन्य पोस्ट के समान है .... लेकिन इस समाधान ने लीप वर्ष के उदाहरणों के लिए काम किया 02/29/1976 से 03/01/2011 / २०११ से ० //०३/२०१२ तक, जो कि लीप ईयर सॉल्यूशन के बारे में आखिरी पोस्ट किया था, उस प्रथम वर्ष के उपयोग के मामले में काम नहीं किया।

SELECT FLOOR(DATEDIFF(DAY, @date1 , @date2) / 365.25)

यहां मिला ।


3

बस जांचें कि क्या नीचे का उत्तर संभव है।

DECLARE @BirthDate DATE = '09/06/1979'

SELECT 
 (
 YEAR(GETDATE()) - YEAR(@BirthDate) - 
 CASE  WHEN (MONTH(GETDATE()) * 100) + DATEPART(dd, GETDATE()) >     
 (MONTH(@BirthDate) * 100) + DATEPART(dd, @BirthDate)
 THEN 1             
 ELSE 0             
 END        
 )

2
DECLARE @DOB datetime
set @DOB ='11/25/1985'

select floor(
( cast(convert(varchar(8),getdate(),112) as int)-
cast(convert(varchar(8),@DOB,112) as int) ) / 10000
)

स्रोत: http://beginsql.wordpress.com/2012/04/26/how-to-calculate-age-in-sql-server/


SQL सर्वर 2012+ में ऐसा करने का एक छोटा तरीका निम्नानुसार है, और 112 में धर्मान्तरित से बचा जाता है और फर्श की आवश्यकता नहीं होती है:code: SELECT [Age] = (0+ FORMAT(@ToDate,'yyyyMMdd') - FORMAT(@DOB,'yyyyMMdd') ) /10000
ukgav

2

मैंने इस बारे में बहुत सारी सोच और खोज की है और मेरे पास 3 समाधान हैं

  • आयु की सही गणना करें
  • कम हैं (अधिकतर)
  • (ज्यादातर) बहुत समझने योग्य हैं।

यहाँ परीक्षण मान हैं:

DECLARE @NOW DATETIME = '2013-07-04 23:59:59' 
DECLARE @DOB DATETIME = '1986-07-05' 

समाधान 1: मुझे यह दृष्टिकोण एक js लाइब्रेरी में मिला। यह मेरा पसंदीदा है।

DATEDIFF(YY, @DOB, @NOW) - 
  CASE WHEN DATEADD(YY, DATEDIFF(YY, @DOB, @NOW), @DOB) > @NOW THEN 1 ELSE 0 END

यह वास्तव में DOB में वर्षों में अंतर जोड़ रहा है और यदि यह वर्तमान तिथि से बड़ा है तो एक वर्ष घटाता है। सरल सही? केवल एक चीज यह है कि वर्षों में अंतर यहां दोहराया गया है।

लेकिन अगर आपको इसे इनलाइन उपयोग करने की आवश्यकता नहीं है, तो आप इसे इस तरह लिख सकते हैं:

DECLARE @AGE INT = DATEDIFF(YY, @DOB, @NOW)
IF DATEADD(YY, @AGE, @DOB) > @NOW
SET @AGE = @AGE - 1

समाधान 2: यह एक जिसे मैंने मूल रूप से @ बेकन-बिट्स से कॉपी किया था। यह समझना सबसे आसान है लेकिन थोड़ा लंबा है।

DATEDIFF(YY, @DOB, @NOW) - 
  CASE WHEN MONTH(@DOB) > MONTH(@NOW) 
    OR MONTH(@DOB) = MONTH(@NOW) AND DAY(@DOB) > DAY(@NOW) 
  THEN 1 ELSE 0 END

यह मूल रूप से उम्र की गणना है जैसा कि हम मनुष्य करते हैं।


समाधान 3: मेरे मित्र ने इसे इस में दर्शाया:

DATEDIFF(YY, @DOB, @NOW) - 
  CEILING(0.5 * SIGN((MONTH(@DOB) - MONTH(@NOW)) * 50 + DAY(@DOB) - DAY(@NOW)))

यह सबसे छोटा है लेकिन इसे समझना सबसे कठिन है। 50सिर्फ एक वजन है इसलिए दिन का अंतर केवल महत्वपूर्ण है जब महीने समान होते हैं। SIGNसमारोह रूपांतरित होने वाले जो कुछ भी यह हो जाता है करने के लिए -1, 0 या 1. मूल्य के लिए है CEILING(0.5 *के रूप में ही है Math.max(0, value)लेकिन वहाँ एसक्यूएल में ऐसी कोई बात नहीं है।


1
CASE WHEN datepart(MM, getdate()) < datepart(MM, BIRTHDATE) THEN ((datepart(YYYY, getdate()) - datepart(YYYY, BIRTH_DATE)) -1 )
     ELSE 
        CASE WHEN datepart(MM, getdate()) = datepart(MM, BIRTHDATE)
            THEN 
                CASE WHEN datepart(DD, getdate()) < datepart(DD, BIRTHDATE) THEN ((datepart(YYYY, getdate()) - datepart(YYYY, BIRTHDATE)) -1 )
                    ELSE (datepart(YYYY, getdate()) - datepart(YYYY, BIRTHDATE))
                END
        ELSE (datepart(YYYY, getdate()) - datepart(YYYY, BIRTHDATE)) END            
    END

1
select floor((datediff(day,0,@today) - datediff(day,0,@birthdate)) / 365.2425) as age

यहां बहुत सारे 365.25 उत्तर हैं। याद रखें कि लीप वर्ष कैसे परिभाषित किए जाते हैं:

  • हर चार वर्ष
    • हर 100 साल को छोड़कर
      • हर 400 साल को छोड़कर

बहुत बढ़िया जवाब। जो लोग यहां उत्सुक हैं, उनके बारे में स्पष्टीकरण है कि 365.2425 का उपयोग करने का सही मूल्य क्यों है: grc.nasa.gov/WWW/k-12/Numbers/Math/Mathematical_Thinking/…
vvvv4d 19

0

इस बारे में कैसा है:

SET @Age = CAST(DATEDIFF(Year, @DOB, @Stamp) as int)
IF (CAST(DATEDIFF(DAY, DATEADD(Year, @Age, @DOB), @Stamp) as int) < 0) 
    SET @Age = @Age - 1

0

इसे इस्तेमाल करे

DECLARE @date datetime, @tmpdate datetime, @years int, @months int, @days int
SELECT @date = '08/16/84'

SELECT @tmpdate = @date

SELECT @years = DATEDIFF(yy, @tmpdate, GETDATE()) - CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END
SELECT @tmpdate = DATEADD(yy, @years, @tmpdate)
SELECT @months = DATEDIFF(m, @tmpdate, GETDATE()) - CASE WHEN DAY(@date) > DAY(GETDATE()) THEN 1 ELSE 0 END
SELECT @tmpdate = DATEADD(m, @months, @tmpdate)
SELECT @days = DATEDIFF(d, @tmpdate, GETDATE())

SELECT Convert(Varchar(Max),@years)+' Years '+ Convert(Varchar(max),@months) + ' Months '+Convert(Varchar(Max), @days)+'days'

0

इस समाधान का प्रयास करें:

declare @BirthDate datetime
declare @ToDate datetime

set @BirthDate = '1/3/1990'
set @ToDate = '1/2/2008'
select @BirthDate [Date of Birth], @ToDate [ToDate],(case when (DatePart(mm,@ToDate) <  Datepart(mm,@BirthDate)) 
        OR (DatePart(m,@ToDate) = Datepart(m,@BirthDate) AND DatePart(dd,@ToDate) < Datepart(dd,@BirthDate))
        then (Datepart(yy, @ToDate) - Datepart(yy, @BirthDate) - 1)
        else (Datepart(yy, @ToDate) - Datepart(yy, @BirthDate))end) Age

0

यह जन्मदिन और गोलाई के साथ मुद्दों को सही ढंग से संभालेंगे:

DECLARE @dob  datetime
SET @dob='1992-01-09 00:00:00'

SELECT DATEDIFF(YEAR, '0:0', getdate()-@dob)

2
लीप वर्ष को सही ढंग से नहीं संभालता है चयनित डेटिफ़ (YEAR, '0: 0', कन्वर्ट (डेटाटाइम, '2014-02-28') -'2012-02-29 ') 2 देता है, लेकिन केवल 1 होना चाहिए
पीटर केर

0

एड हार्पर का हल सबसे सरल है जो मैंने पाया है जो कभी गलत उत्तर नहीं देता है जब दो तारीखों का महीना और दिन 1 या दो दिन अलग होते हैं। मैंने नकारात्मक उम्र को संभालने के लिए थोड़ा संशोधन किया।

DECLARE @D1 AS DATETIME, @D2 AS DATETIME
SET @D2 = '2012-03-01 10:00:02'
SET @D1 = '2013-03-01 10:00:01'
SELECT
   DATEDIFF(YEAR, @D1,@D2)
   +
   CASE
      WHEN @D1<@D2 AND DATEADD(YEAR, DATEDIFF(YEAR,@D1, @D2), @D1) > @D2
      THEN - 1
      WHEN @D1>@D2 AND DATEADD(YEAR, DATEDIFF(YEAR,@D1, @D2), @D1) < @D2
      THEN 1
      ELSE 0
   END AS AGE

0

सही के रूप में चिह्नित उत्तर सटीकता के करीब है, लेकिन, यह निम्नलिखित परिदृश्य में विफल रहता है - जहां वर्ष का जन्म वर्ष है और फरवरी माह के बाद दिन है

declare @ReportStartDate datetime = CONVERT(datetime, '1/1/2014'),
@DateofBirth datetime = CONVERT(datetime, '2/29/1948')

FLOOR(DATEDIFF(HOUR,@DateofBirth,@ReportStartDate )/8766)


या

FLOOR(DATEDIFF(HOUR,@DateofBirth,@ReportStartDate )/8765.82) -- Divisor is more accurate than 8766

- निम्नलिखित समाधान मुझे और अधिक सटीक परिणाम दे रहे हैं।

FLOOR(DATEDIFF(YEAR,@DateofBirth,@ReportStartDate) - (CASE WHEN DATEADD(YY,DATEDIFF(YEAR,@DateofBirth,@ReportStartDate),@DateofBirth) > @ReportStartDate THEN 1 ELSE 0 END ))

इसने लगभग सभी परिदृश्यों में काम किया, जिसमें लीप वर्ष, तिथि को 29 फेब, आदि पर विचार किया गया।

कृपया मुझे सुधारे अगर इस फॉर्मूले में कोई खामी है।


अंतिम सूत्र इस उत्तर में लगभग सटीक है जैसे stackoverflow.com/a/1572235/168747 । लेकिन यहाँ एक कम पठनीय है और इसमें अनावश्यक है floor
मारेक


0

यहाँ बताया गया है कि मैं किस प्रकार जन्म तिथि और वर्तमान तिथि की गणना करता हूँ।

select case 
            when cast(getdate() as date) = cast(dateadd(year, (datediff(year, '1996-09-09', getdate())), '1996-09-09') as date)
                then dateDiff(yyyy,'1996-09-09',dateadd(year, 0, getdate()))
            else dateDiff(yyyy,'1996-09-09',dateadd(year, -1, getdate()))
        end as MemberAge
go

0
CREATE function dbo.AgeAtDate(
    @DOB    datetime,
    @CompareDate datetime
)

returns INT
as
begin

return CASE WHEN @DOB is null
THEN 
    null
ELSE 
DateDiff(yy,@DOB, @CompareDate) 
- CASE WHEN datepart(mm,@CompareDate) > datepart(mm,@DOB) OR (datepart(mm,@CompareDate) = datepart(mm,@DOB) AND datepart(dd,@CompareDate) >= datepart(dd,@DOB))
  THEN 0 
  ELSE 1
  END
END
End

GO

-1: गलत किसी भी समय हो जाएगा month(compare) > month(dob)लेकिन day(compare) < day(dob), जैसे select dbo.AgeAtDate('2000-01-14', '2016-02-12')
जॉनब्रवे

आप सही हैं, इस मामले के लिए धन्यवाद, अपडेट किया गया कार्य
Vova

0
DECLARE @FromDate DATETIME = '1992-01-2623:59:59.000', 
        @ToDate   DATETIME = '2016-08-10 00:00:00.000',
        @Years INT, @Months INT, @Days INT, @tmpFromDate DATETIME
SET @Years = DATEDIFF(YEAR, @FromDate, @ToDate)
 - (CASE WHEN DATEADD(YEAR, DATEDIFF(YEAR, @FromDate, @ToDate),
          @FromDate) > @ToDate THEN 1 ELSE 0 END) 


SET @tmpFromDate = DATEADD(YEAR, @Years , @FromDate)
SET @Months =  DATEDIFF(MONTH, @tmpFromDate, @ToDate)
 - (CASE WHEN DATEADD(MONTH,DATEDIFF(MONTH, @tmpFromDate, @ToDate),
          @tmpFromDate) > @ToDate THEN 1 ELSE 0 END) 

SET @tmpFromDate = DATEADD(MONTH, @Months , @tmpFromDate)
SET @Days =  DATEDIFF(DAY, @tmpFromDate, @ToDate)
 - (CASE WHEN DATEADD(DAY, DATEDIFF(DAY, @tmpFromDate, @ToDate),
          @tmpFromDate) > @ToDate THEN 1 ELSE 0 END) 

SELECT @FromDate FromDate, @ToDate ToDate, 
       @Years Years,  @Months Months, @Days Days

0

केवल तारीख कार्यों के साथ एक समाधान के बारे में क्या, गणित नहीं, लीप वर्ष के बारे में चिंता नहीं

CREATE FUNCTION dbo.getAge(@dt datetime) 
RETURNS int
AS
BEGIN
    RETURN 
        DATEDIFF(yy, @dt, getdate())
        - CASE 
            WHEN 
                MONTH(@dt) > MONTH(GETDATE()) OR 
                (MONTH(@dt) = MONTH(GETDATE()) AND DAY(@dt) > DAY(GETDATE())) 
            THEN 1 
            ELSE 0 
        END
END

0

MANY विधियों को आज़माने के बाद, यह कन्वर्ट करने के लिए आधुनिक MS SQL FORMAT फ़ंक्शन का उपयोग करने के बजाय 100% समय में 112 कार्य करता है। या तो काम करेगा लेकिन यह सबसे कम कोड है।

क्या किसी को एक तारीख संयोजन मिल सकता है जो काम नहीं करता है? मुझे नहीं लगता कि कोई एक है :)

--Set parameters, or choose from table.column instead:

DECLARE @DOB    DATE = '2000/02/29' -- If @DOB is a leap day...
       ,@ToDate DATE = '2018/03/01' --...there birthday in this calculation will be 

--0+ part tells SQL to calc the char(8) as numbers:
SELECT [Age] = (0+ FORMAT(@ToDate,'yyyyMMdd') - FORMAT(@DOB,'yyyyMMdd') ) /10000

-2

हमने यहां कुछ का उपयोग किया, लेकिन फिर औसत आयु लेते हुए:

ROUND(avg(CONVERT(int,DATEDIFF(hour,DOB,GETDATE())/8766.0)),0) AS AverageAge

ध्यान दें, ROUND अंदर की बजाय बाहर है। यह AVG को अधिक सटीक बनाने की अनुमति देगा और हम केवल एक बार ROUND करेंगे। इसे और तेज करना।



-2
SELECT CAST(DATEDIFF(dy, @DOB, GETDATE()+1)/365.25 AS int)

मुझे वोट दिखाई देते हैं लेकिन मुझे ऐसे उदाहरण नहीं दिखते हैं जो यह साबित करते हैं कि यह टूट गया है।
एलेक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.