জন্মের তারিখ এবং getDate () এর ভিত্তিতে বয়স (বছরগুলিতে) কীভাবে গণনা করা যায়


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
আপনি ডাটাবেসের নেটিভ ডেট বা ডেটটাইম টাইপের পরিবর্তে এনভারচচার (25) ব্যবহার করে স্ট্রিং হিসাবে তারিখের মানগুলি কেন সংরক্ষণ করছেন?
জেস্পার

প্রশ্নটি ২০০ 2005 সালে নয় ২০০৮ সালে ট্যাগ করা হয়েছে, ফলে দেশীয় 'তারিখ' প্রকারটি উপলভ্য নয়, তবে এটি অবশ্যই একটি তারিখের সময়, এবং আপনার সঠিকতার প্রয়োজন হয় না বলে এটি স্মার্টডটাইম যুক্তিযুক্ত হতে পারে।
অ্যান্ড্রু

হাই, তারিখগুলি ভারচার হিসাবে রাখার কারণ হ'ল আমি এটি কোনও এস -কিউএল সার্ভারের স্কিমা থেকে আমদানি করছি, তাদের ডেটটাইম (এবং অন্যান্য তারিখের ফর্ম্যাট) রূপে আমদানি করার কিছু সমস্যা ছিল এবং বর্ণচরিত ঠিক আছে
জিমি

7
@ জেমস.এলসি, সুতরাং আপনার আমদানি করার সমস্যা ছিল এবং ফলস্বরূপ সমস্ত তারিখ বৈধ? আপনি একবারে ডেটটাইম বা স্মার্টডেটটাইম ব্যবহার না করে কখনও নিশ্চিত হতে পারবেন না, ভারচারের সাহায্যে আপনি নিজের আমদানিটি কাজে লাগতে পারেন, তবে অন্যান্য সমস্যার মধ্যে নেই। এছাড়াও, আমি কখনও বয়সটি সঞ্চয় করি না, এটি প্রতিদিন পরিবর্তিত হয়, একটি ভিউ
কেএম

@ কেএম হ্যাঁ, তারিখ হিসাবে ডেটা আমদানি করার ক্ষেত্রে একটি সমস্যা ছিল, সেই সময়ের একমাত্র কার্যকর সমাধান ছিল এনভারচার হিসাবে তাদের আমদানি করা। এই নির্বাচনটি একটি রাত্রে কাজের অংশ হতে চলেছে তাই বয়স সংরক্ষণ করা কোনও সমস্যা হওয়া উচিত নয়
জিমি

উত্তর:


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
এটিও সঠিক সমাধান নয়। যদি আমি আমার নিজের @ ডবকে '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
বার্টলাহারোভেন

20
এটি যথাযথ নয় কারণ এটি প্রতি বছর 8766 ঘন্টা ধরে নেয় যা 365.25 দিন পর্যন্ত কাজ করে। যেহেতু 365.25 দিন সহ কোনও বছর নেই, তাই এটি সঠিক হওয়ার চেয়ে ব্যক্তির জন্মের তারিখের নিকটে ভুল হবে। এই পদ্ধতিটি এখনও আরও সঠিক হতে চলেছে।
বেকন বিট

1
দ্বিতীয় @ বেকন বিটস মন্তব্য করেছেন - বর্তমান তারিখটি কোনও ব্যক্তির জন্ম তারিখের কাছাকাছি থাকলে এটি প্রায়শই ভুল হবে।
ফ্ল্যাশ

2
আমি মনে করি পাঠ্যের প্রথম ব্লকটি এই উত্তরটিকে বিভ্রান্তিকর করে তোলে। যদি আপনার আপডেট হওয়া পদ্ধতিটিতে লিপ বছরগুলিতে সমস্যা না থাকে তবে আমি এটিকে আপনার উত্তরের নীচে সরানোর পরামর্শ দিই (যদি আপনি সত্যিই এটিকে কিছুতেই রাখতে চান)।
আজবাইভেন

1
আপনি একটি চান EXACT হিসাব, তারপর DATEDIFF এটা ইত্যাদি কি করতে হবে না @ShailendraMishra, কারণ এটি দিন পরিমাপক। উদাহরণস্বরূপ, select datediff(year, '2000-01-05', '2018-01-04')17 টি যেমনটি দেওয়া উচিত তেমন নয়। আমি "বুদ্ধিমানের জন্য সেরা পদ্ধতি" শিরোনামে উপরোক্ত উদাহরণটি ব্যবহার করেছি এবং এটি পুরোপুরি কার্যকরভাবে কাজ করে। ধন্যবাদ!
ওপেনওনক

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 কনভার্ট ফাংশনের জন্য একটি বিশেষ সংখ্যা যা তারিখটি yyyymmdd হিসাবে ফর্ম্যাট করে। আপনি যখন এটি তাকান এটি সম্ভবত সবার পক্ষে স্পষ্ট নয়।
ডেরেক টোমস

5
তুমি একজন প্রতিভাবান!
ইরকান

আমার দল যখন ইস্যুটি ব্যবহার করার জন্য বয়সটি ব্যবহার করার জন্য যে তারিখটি ব্যবহার করেছিলাম তার সাথে আমরা যে তারিখটি তুলনা করি ঠিক একই দিনটি তখন একটি সমস্যা নিয়ে চলেছিল। আমরা লক্ষ্য করছিলাম যে যখন তারা একই দিন ছিল (এবং যদি বয়সটি বিজোড় হতে চলেছিল) তখন বয়সটি একের পর এক বন্ধ হয়ে যাবে। এটি নিখুঁতভাবে কাজ করেছে!
শিখ গীক

1
এটি সঠিক উত্তর - দয়া করে এটি চিহ্নিত করুন।
স্নেম্পি

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

উপরোক্ত সমাধানগুলির মধ্যে অনেকগুলিই ভুল ডেটডিফ (yy, @ ডাব, @ প্যাসেডডেট) উভয় তারিখের মাস এবং দিন বিবেচনা করবে না। এছাড়াও ডার্ট অংশগুলি নিয়ে যাওয়া এবং তুলনা করা কেবলমাত্র যদি তাদের যথাযথ অর্ডার দেওয়া হয় তবে কাজ করে।

অনুসরণ কোড এবং কাজ খুব সহজ:

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
ধন্যবাদ! ঠিক এখানে কোডটি আমি আশা করছিলাম। (কুরুচিপূর্ণ) স্ট্রিং ট্রান্সফর্মেশনগুলি ছাড়াই এই থ্রেডে এটিই কেবল সঠিক কোড! @ জেন এটি ডিওবির মাস এবং দিন সময় নেয় (25 সেপ্টেম্বর এর মতো) এবং এটি একটি পূর্ণসংখ্যার মান 0925(বা 925) রূপান্তর করে । এটি বর্তমান তারিখের সাথে একই রকম হয় (১ December ই ডিসেম্বরের মতো 1216) এবং তারপরে ডওবি সংখ্যার মানটি ইতিমধ্যে পাস হয়েছে কিনা তা পরীক্ষা করে। এই পূর্ণসংখ্যাটি তৈরি করতে,
মাসটি

ধন্যবাদ @ বার্টলাহারোভেন :)
জেন

আমি কেবল উল্লেখ করব যে এটি স্ট্রিং ট্রান্সফর্মেশনগুলি এড়ায় না, পরিবর্তে এটি প্রচুর কাস্টিং করে। আমার পরীক্ষাটি দেখায় যে এটি ডটজয়ের উত্তরের চেয়ে উল্লেখযোগ্যভাবে দ্রুত নয় এবং কোডটি আরও ভার্জোজ
স্ট্রিপলিং ওয়ারিয়র

গৃহীত উত্তরের অনেক সহজ আইএনটি উত্তর রয়েছে:(CONVERT(int,CONVERT(char(8),@Now,112))-CONVERT(char(8),@Dob,112))/10000
কেএম।

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>

যা আমি এখান থেকে মানিয়ে নিয়েছি ।

নোট করুন যে এটি ২৮ শে ফেব্রুয়ারিকে নন-লিপ বছরের জন্য একটি লাফনের জন্মদিন হিসাবে বিবেচনা করবে উদাহরণস্বরূপ, ২০২০ সালের ২৯ ফেব্রুয়ারি জন্ম নেওয়া একজন ব্যক্তিকে 01 মার্চ 2021 এর পরিবর্তে ২৮ ফেব্রুয়ারী ২০২১ সালে এক বছর বয়সী হিসাবে বিবেচনা করা হবে।


@ অ্যান্ড্রু - সংশোধন হয়েছে - আমি বিকল্পগুলির মধ্যে একটিটি মিস করেছি
এড হার্পার

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/489865 উপরের পোস্টে মন্তব্য করেছেন যেখানে তিনি বলেছেন:

যদি আমরা মানুষের বয়সের কথা বলছি তবে মানুষ যেভাবে বয়সের গণনা করে তা আপনার এটি গণনা করা উচিত। পৃথিবী কীভাবে দ্রুত গতি সঞ্চার করে এবং ক্যালেন্ডারের সাথে সবকিছু করার সাথে এর কিছুই করার নেই। প্রতিবার একই মাস এবং দিন জন্মের তারিখ হিসাবে বিচ্ছিন্ন হয়ে যায়, আপনি বয়স 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

[দ্রষ্টব্য: এসকিউএল বিওএল / এমএসডিএন-তে কোথাও নেই যা DATEPART(dayofyear, ...)রিটার্নগুলি আসলে নথিভুক্ত করে! আমি এটিকে 1--366 পরিসরের একটি নম্বর বলে বুঝতে পারি; সর্বাধিক গুরুত্বপূর্ণ বিষয় হল এটি স্থানীয় অনুসারে & ।] অনুযায়ী পরিবর্তন হয় না ]DATEPART(weekday, ...)SET DATEFIRST


সম্পাদনা করুন: কেন dayofyearগোলমাল : ব্যবহারকারী হিসাবে @AeroX মন্তব্য করেছে, যদি জন্ম / শুরুর তারিখের একটি অ অধিবর্ষ ফেব্রুয়ারী পরে, বয়স একদিন গোড়ার দিকে বৃদ্ধি হয় যখন বর্তমান / শেষ তারিখ একটি লীপ বছর, যেমন '2015-05-26', '2016-05-25'একটি দেয় 1 বছর বয়স যখন এখনও 0 হওয়া উচিত তখন dayofyearবিভিন্ন বছরের সাথে তুলনা করা স্পষ্টতই বিপজ্জনক। সুতরাং ব্যবহার MONTH()এবং DAY()সর্বোপরি প্রয়োজনীয়।


এটিতে ভোট দেওয়া উচিত বা এমনকি উত্তর হিসাবে চিহ্নিত করা উচিত। এটি সংক্ষিপ্ত, মার্জিত এবং যৌক্তিকভাবে সঠিক।
z00l

1
ফেব্রুয়ারির পরে জন্মগ্রহণকারী প্রত্যেকের জন্য DayOfYearপদ্ধতিটি ব্যবহার করে প্রতি লিপ বছরে প্রথম দিকে তাদের বয়স বাড়ানো হয় incre
AeroX

4
@ অ্যারোএক্স এই ত্রুটি চিহ্নিত করার জন্য আপনাকে ধন্যবাদ। আমি আমার সমাধানটি যে কারও কাছে হতে পারে বা ব্যবহার 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', গেটডেট ()) 1 বছর বয়সের রিপোর্ট করবে তবে তারা কেবল 10 মাস বয়সী হবে ।
অ্যান্ড্রু

1
এই গণনাটি এমন লোকদের জন্য ভুল গণনা দেয় যাঁদের এই বছরের জন্মদিন এখনও হয়নি।

3

কি সম্পর্কে:

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

এটি কি এই সমস্ত বৃত্তাকার, কাটছাঁটি করা এবং সংলগ্ন সমস্যাগুলি এড়ানো যাবে না?


আপনার গণনা সঠিক নয়। উদাহরণস্বরূপ: আপনি '1986-07-05 00:00:00'ডিওবি এবং '2013-07-04 23:59:59'বর্তমান সময়ের জন্য গ্রহণ করলে এটি ব্যর্থ হয় ।
drinovc

@ub_coding আপনি কি অফার করছেন এবং উত্তর দিচ্ছেন বা অন্য প্রশ্ন জিজ্ঞাসা করছেন?
অ্যারন সি

এটি: @DOB ডেটটাইম SET @ ডিওবি = '19760229' নির্বাচন করুন তারিখ পার্ট (yy, রূপান্তর (ডেটটাইম, '19770228') - @ ডিওবি) -1900 = 1 মূল সমস্যাটি বেশিরভাগ সমাধানের জন্য 29 মাপের ফাঁক, এটি সংক্ষিপ্তভাবে গোল কাটা ইত্যাদি ব্যাখ্যা করে etc ।
লিওনার্দো মার্কস ডি সুজা

3

আমি বিশ্বাস করি এটি এখানে পোস্ট করা অন্যান্যগুলির সাথে একই রকম .... তবে এই সমাধানটি লিপ ইয়ার উদাহরণগুলিতে 02/29/1976 থেকে 03/01/2011 পর্যন্ত কাজ করেছে এবং প্রথম বছরের জন্যও মামলার পক্ষে কাজ করেছে .. যেমন 07/04 / ২০১১ থেকে 07/03/2012 যা সর্বশেষ লিপ ইয়ার সলিউশন সম্পর্কে পোস্ট করেছে এটি প্রথম বছরের ব্যবহারের ক্ষেত্রে কার্যকর হয়নি।

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: আমি এই পদ্ধতিটি একটি জেএস লাইব্রেরিতে পেয়েছি। এটা আমার প্রিয়।

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

এটি আসলে ডিওবিতে বছরগুলিতে পার্থক্য যুক্ত করে এবং যদি এটি বর্তমান তারিখের চেয়ে বড় হয় তবে এক বছর বিয়োগ করে। সহজ? একমাত্র জিনিস বছরের বিভিন্ন পার্থক্য এখানে নকল করা হয়।

তবে যদি আপনাকে এটি ইনলাইন ব্যবহার করার প্রয়োজন না হয় তবে আপনি এটি এইভাবে লিখতে পারেন:

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/WW/k-12/ সংখ্যা
ম্যাথ

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
লিপ বছর সঠিকভাবে পরিচালনা করে না DATEDIFF (YEAR, '0: 0', রূপান্তর (তারিখের সময়, '2014-02-28') -'2012-02-29 ') 2 দেয়, তবে কেবল 1 হওয়া উচিত
পিটার কের

0

এড হার্পারের সমাধানটি আমি সবচেয়ে সহজ পেয়েছি যা দুটি তারিখের মাস এবং দিন এক বা তার কম দিন বাদে কখনই ভুল উত্তর দেয় না। নেতিবাচক বয়সগুলি পরিচালনা করতে আমি কিছুটা পরিবর্তন করেছি।

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 ফেব ইত্যাদি বিবেচনা করে প্রায় সব পরিস্থিতিতে কাজ করেছিল

এই সূত্রের কোনও ফাঁক থাকলে দয়া করে আমাকে সংশোধন করুন।


চূড়ান্ত সূত্রটি প্রায় উত্তরের মতো স্ট্যাকওভারফ্লো . com/a/1572235/168747 like তবে এখানে একটি কম পাঠযোগ্য এবং এতে অপ্রয়োজনীয় রয়েছে 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')
জোনব্রেভ

আপনি ঠিক বলেছেন, এই মামলার জন্য আপনাকে ধন্যবাদ, ফাংশনটি আপডেট করেছেন
ভোভা

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

অনেকগুলি পদ্ধতির চেষ্টা করার পরে, এটি আধুনিক এমএস এসকিউএল ফর্ম্যাট ফাংশনটি ব্যবহার করে শৈল 112 এ রূপান্তরিত না করে 100% সময় কাজ করে ither হয় কাজ করবে তবে এটি সর্বনিম্ন কোড is

কাজ করে না এমন কোনও তারিখের সংমিশ্রণটি কি কেউ খুঁজে পেতে পারেন? আমি মনে করি না একটি আছে :)

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

লক্ষ্য করুন, রাউন্ডটি ভিতরে না থেকে বাইরে। এটি এভিজিকে আরও নির্ভুল হওয়ার অনুমতি দেবে এবং আমরা কেবল একবারে গোল করব। এটি আরও দ্রুত তৈরি করা।



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

আমি ভোটগুলি নীচে দেখছি তবে উদাহরণগুলি দেখতে পাচ্ছি না যা প্রমাণ করে যে এটি ভঙ্গ হয়েছে।
অ্যালেক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.