Saya memiliki tabel yang mencantumkan orang beserta tanggal lahirnya (saat ini nvarchar (25))
Bagaimana saya bisa mengonversi itu menjadi tanggal, dan kemudian menghitung usia mereka dalam tahun?
Data saya terlihat sebagai berikut
ID Name DOB
1 John 1992-01-09 00:00:00
2 Sally 1959-05-20 00:00:00
Saya ingin melihat:
ID Name AGE DOB
1 John 17 1992-01-09 00:00:00
2 Sally 50 1959-05-20 00:00:00
Jawaban:
Ada masalah dengan tahun kabisat / hari dan metode berikut, lihat pembaruan di bawah ini:
UPDATE di sini adalah beberapa metode yang lebih akurat:
METODE TERBAIK UNTUK TAHUN DI INT
Anda dapat mengubah di atas
10000
ke10000.0
dan mendapatkan desimal, tetapi itu tidak akan seakurat metode di bawah ini.METODE TERBAIK UNTUK TAHUN DI DESIMAL
sumber
GETDATE()
) pada '2013-07-04 23:59:59' katanya, saya Sedang 27, sementara pada saat itu, saya belum. Kode contoh: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
select datediff(year, '2000-01-05', '2018-01-04')
mengembalikan 18, bukan 17 sebagaimana mestinya. Saya menggunakan contoh di atas di bawah judul "METODE TERBAIK UNTUK TAHUN DALAM INT" dan itu berfungsi dengan baik. Terima kasih!Harus membuang yang ini di luar sana. Jika Anda mengonversi tanggal menggunakan gaya 112 (yyyymmdd) ke angka, Anda dapat menggunakan perhitungan seperti ini ...
(yyyyMMdd - yyyyMMdd) / 10000 = perbedaan dalam tahun penuh
keluaran
sumber
code: SELECT [Age] = (0+ FORMAT(@as_of,'yyyyMMdd') - FORMAT(@bday,'yyyyMMdd') ) /10000 --The 0+ part tells SQL to calc the char(8) as numbers
Saya telah menggunakan kueri ini dalam kode produksi kami selama hampir 10 tahun:
sumber
DATEDIFF(yy, @BirthDate, GETDATE()) - CASE WHEN (MONTH(@BirthDate) >= MONTH(GETDATE())) AND DAY(@BirthDate) > DAY(GETDATE()) THEN 1 ELSE 0 END
CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END
Begitu banyak solusi di atas yang salah DateDiff (yy, @ Dob, @PassedDate) tidak akan mempertimbangkan bulan dan hari dari kedua tanggal. Juga mengambil bagian panah dan membandingkan hanya berfungsi jika mereka dipesan dengan benar.
KODE BERIKUT INI BEKERJA DAN SANGAT SEDERHANA:
sumber
0925
(atau925
). Itu melakukan hal yang sama dengan tanggal saat ini (seperti 16 Desember menjadi1216
) dan kemudian memeriksa apakah nilai integer DoB telah berlalu. Untuk membuat bilangan bulat ini, bulan harus dikalikan dengan 100.(CONVERT(int,CONVERT(char(8),@Now,112))-CONVERT(char(8),@Dob,112))/10000
Anda perlu mempertimbangkan cara putaran perintah Dateiff.
Yang saya adaptasi dari sini .
Perhatikan bahwa itu akan mempertimbangkan 28 Februari sebagai hari ulang tahun lompatan untuk tahun-tahun non-lompatan misalnya orang yang lahir pada tanggal 29 Februari 2020 akan dianggap berusia 1 tahun pada tanggal 28 Februari 2021 alih-alih 01 Mar 2021.
sumber
SELECT DATEDIFF(year, DOB, getdate()) + CASE WHEN (DATEADD(year,DATEDIFF(year, DOB, getdate()) , DOB) > getdate()) THEN - 1 ELSE 0 END)
EDIT: JAWABAN INI TIDAK BENAR. Saya meninggalkannya di sini sebagai peringatan bagi siapa saja yang tergoda untuk menggunakannya
dayofyear
, dengan pengeditan lebih lanjut di bagian akhir.Jika, seperti saya, Anda tidak ingin membaginya dengan hari pecahan atau risiko pembulatan / tahun kabisat, saya memuji komentar @Bacon Bits dalam pos di atas https://stackoverflow.com/a/1572257/489865 di mana ia berkata:
Dia kemudian menawarkan:
Ada beberapa saran di sini yang melibatkan membandingkan bulan & hari (dan ada yang salah, gagal mengizinkannya dengan
OR
benar di sini!). Tapi tidak ada yang menawarkandayofyear
, yang tampak sangat sederhana dan jauh lebih pendek. Saya menawarkan:[Catatan: Tidak ada dalam SQL BOL / MSDN yang
DATEPART(dayofyear, ...)
mengembalikan benar-benar didokumentasikan! Saya memahaminya sebagai angka dalam kisaran 1--366; yang paling penting, itu tidak berubah menurut lokal sesuaiDATEPART(weekday, ...)
&SET DATEFIRST
.]EDIT: Mengapa
dayofyear
salah : Sebagai pengguna @AeroX telah berkomentar, jika tanggal lahir / mulai adalah setelah Februari di tahun bukan kabisat, usia bertambah satu hari lebih awal ketika tanggal saat ini / akhir adalah tahun kabisat, misalnya'2015-05-26'
,'2016-05-25'
memberikan usia 1 ketika masih harus 0. Membandingkandayofyear
di tahun yang berbeda jelas berbahaya. Jadi menggunakanMONTH()
danDAY()
diperlukan setelah semua.sumber
DayOfYear
metode ini.dayofyear
, tetapi diedit dengan jelas untuk menunjukkan mengapa itu salah. Saya harap itu cocok.Karena tidak ada satu jawaban sederhana yang selalu memberikan usia yang benar, inilah yang saya temukan.
Ini mendapatkan perbedaan tahun antara tanggal lahir dan tanggal saat ini. Maka dikurangi satu tahun jika tanggal lahir belum berlalu.
Akurat setiap saat - terlepas dari tahun kabisat atau seberapa dekat dengan tanggal lahir.
Terbaik dari semuanya - tidak ada fungsi.
sumber
sumber
Bagaimana dengan:
Bukankah itu akan menghindari semua masalah pembulatan, pemangkasan, dan ofsetting?
sumber
'1986-07-05 00:00:00'
untuk DOB dan'2013-07-04 23:59:59'
untuk waktu saat ini.Saya percaya ini mirip dengan yang lain diposting di sini .... tetapi solusi ini bekerja untuk contoh tahun kabisat 02/29/1976 hingga 03/01/2011 dan juga bekerja untuk kasus ini untuk tahun pertama .. seperti 07/04 / 2011 hingga 07/03/2012 yang terakhir diposting tentang solusi tahun kabisat tidak berfungsi untuk kasus penggunaan tahun pertama.
Ditemukan di sini .
sumber
sumber
sumber: http://beginsql.wordpress.com/2012/04/26/how-to-calculate-age-in-sql-server/
sumber
code: SELECT [Age] = (0+ FORMAT(@ToDate,'yyyyMMdd') - FORMAT(@DOB,'yyyyMMdd') ) /10000
Saya telah melakukan banyak pemikiran dan mencari tentang ini dan saya punya 3 solusi itu
Berikut adalah nilai-nilai pengujian:
Solusi 1: Saya menemukan pendekatan ini di satu perpustakaan js. Itu favorit saya.
Ini sebenarnya menambah perbedaan tahun ke DOB dan jika lebih besar dari tanggal saat ini maka kurangi satu tahun. Sederhana bukan? Satu-satunya hal adalah perbedaan dalam tahun digandakan di sini.
Tetapi jika Anda tidak perlu menggunakannya sebaris, Anda dapat menulisnya seperti ini:
Solusi 2: Yang ini saya awalnya salin dari @ bacon-bits. Ini yang paling mudah dimengerti tapi agak lama.
Ini pada dasarnya menghitung usia seperti halnya manusia.
Solusi 3: Teman saya refactored ke dalam ini:
Yang ini adalah yang terpendek tetapi paling sulit untuk dipahami.
50
hanya berat sehingga perbedaan hari hanya penting ketika bulan adalah sama.SIGN
fungsi untuk mengubah nilai apa pun yang didapat menjadi -1, 0 atau 1.CEILING(0.5 *
sama denganMath.max(0, value)
tetapi tidak ada hal seperti itu dalam SQL.sumber
sumber
Ada banyak 365,25 jawaban di sini. Ingat bagaimana tahun kabisat didefinisikan:
sumber
Bagaimana dengan ini:
sumber
Coba ini
sumber
Coba solusi ini:
sumber
Ini akan menangani masalah dengan ulang tahun dan pembulatan dengan benar:
sumber
Solusi Ed Harper adalah yang paling sederhana yang saya temukan yang tidak pernah mengembalikan jawaban yang salah ketika bulan dan hari dari dua tanggal terpisah 1 atau kurang hari. Saya membuat sedikit modifikasi untuk menangani zaman negatif.
sumber
Jawaban yang ditandai sebagai benar lebih dekat ke akurasi tetapi, gagal dalam skenario berikut - di mana Tahun kelahiran adalah tahun dan hari kabisat setelah bulan Februari
ATAU
- Solusi berikut memberi saya hasil yang lebih akurat.
Ini bekerja di hampir semua skenario, mengingat tahun kabisat, tanggal 29 Februari, dll.
Harap perbaiki saya jika rumus ini memiliki celah.
sumber
floor
.sumber
Berikut ini cara menghitung usia yang diberikan tanggal lahir dan tanggal saat ini.
sumber
sumber
month(compare) > month(dob)
TETAPIday(compare) < day(dob)
, misselect dbo.AgeAtDate('2000-01-14', '2016-02-12')
.sumber
Bagaimana dengan solusi dengan hanya fungsi tanggal, bukan matematika, tidak khawatir tentang tahun kabisat
sumber
Setelah mencoba metode BANYAK, ini berfungsi 100% dari waktu menggunakan fungsi MS SQL FORMAT modern alih-alih dikonversi ke gaya 112. Entah akan bekerja tetapi ini adalah kode paling sedikit.
Adakah yang bisa menemukan kombinasi tanggal yang tidak berfungsi? Saya tidak berpikir ada :)
sumber
Kami menggunakan sesuatu seperti di sini, tetapi kemudian mengambil usia rata-rata:
Perhatikan, ROUND berada di luar daripada di dalam. Ini akan memungkinkan AVG menjadi lebih akurat dan kami ROUND hanya sekali. Membuatnya lebih cepat juga.
sumber
sumber
sumber