2008-11-12 36 views
8

Trong cơ sở dữ liệu SQL Server, tôi ghi lại ngày sinh của mọi người. Có một phương pháp thẳng về làm việc trong độ tuổi của người đó vào một ngày nhất định chỉ sử dụng SQL không?Tìm tuổi của một người nào đó trong SQL

Sử dụng DATEDIFF (YEAR, DateOfBirth, GETDATE()) không hoạt động vì chỉ nhìn vào phần năm của ngày. Ví dụ DATEDIFF (NĂM, '31 Tháng 12 năm 2007' , '01 Tháng 1 2008') lợi nhuận 1.

Trả lời

21

Kiểm tra bài viết này: How to calculate age of a person using SQL codes

Đây là mã từ bài viết:

DECLARE @BirthDate DATETIME 
DECLARE @CurrentDate DATETIME 

SELECT @CurrentDate = '20070210', @BirthDate = '19790519' 

SELECT DATEDIFF(YY, @BirthDate, @CurrentDate) - CASE WHEN((MONTH(@BirthDate)*100 + DAY(@BirthDate)) > (MONTH(@CurrentDate)*100 + DAY(@CurrentDate))) THEN 1 ELSE 0 END 
+2

Bạn có thể đặt mã thích hợp trong câu trả lời của mình không? Các liên kết đến các trang web khác có thể (và thực hiện), và vì vậy trong tương lai, câu trả lời này có thể không hữu ích nếu liên kết không còn hoạt động nữa. –

+0

@Tim C +1 để đề xuất thêm mã kể từ khi trang web hiện đang ngừng hoạt động và câu trả lời này sẽ vô dụng chỉ với một liên kết. –

5

có một cách khác đó là một chút đơn giản hơn:

Select CAST(DATEDIFF(hh, [birthdate], GETDATE())/8766 AS int) AS Age 

Bởi vì làm tròn ở đây là rất hạt, đây là gần như hoàn toàn chính xác. Các trường hợp ngoại lệ rất phức tạp đến nỗi chúng gần như hài hước: mỗi năm thứ tư tuổi trở lại sẽ là một năm quá trẻ nếu chúng tôi A) yêu cầu tuổi trước 6:00 sáng, B) vào ngày sinh nhật của người đó và C) sinh nhật của họ sau Ngày 28 tháng 2. Trong bối cảnh của tôi, đây là một thỏa hiệp hoàn toàn chấp nhận được.

+0

Nếu bạn thay thế GETDATE() bằng một giá trị tĩnh, bạn sẽ nhấn ngoại lệ thường xuyên hơn kể từ khi bạn kiểm tra vào lúc nửa đêm. Có vẻ như kiểm tra từ trưa thay vì nửa đêm sẽ hoạt động. – Guvante

2

FWIW, Tuổi có thể được tính một cách đơn giản mà không cần đến hacks (không có bất cứ điều gì sai trái với hacks!):

CREATE FUNCTION Age (@BirthDate DATETIME) 
RETURNS INT 
AS 
BEGIN 
    DECLARE @AgeOnBirthdayThisYear INT 
    DECLARE @BirthdayThisYear DATETIME 
    SET @AgeOnBirthdayThisYear = DATEDIFF(year, @BirthDate, GETDATE()) 
    SET @BirthdayThisYear = DATEADD(year, @AgeOnBirthdayThisYear, @BirthDate) 
    RETURN 
     @AgeOnBirthdayThisYear 
     - CASE WHEN @BirthdayThisYear > GETDATE() THEN 1 ELSE 0 END 
END 
1

chương trình Giải pháp này như thế nào trong một truy vấn mà không biến

SELECT DATEDIFF(YY, birthdate, GETDATE()) - CASE WHEN((MONTH(birthdate)*100 + DAY(birthdate)) > (MONTH(GETDATE())*100 + DAY(GETDATE()))) THEN 1 ELSE 0 END 
1

Điều này ngắn gọn hơn và nhanh hơn một chút so với các câu trả lời được cung cấp và hoàn toàn chính xác:

datediff(year,DateOfBirth,getdate()-datepart(dy,DateOfBirth)+1) 
+0

Phương thức này không hoạt động khi GetDate() là ngày sinh. Đây là một ví dụ mà người đó phải 40 tuổi nhưng nó chỉ trả về 39. 'CHỌN dateiff (năm, '1/29/1973', CAST ('1/29/2013' AS DATETIME) -datepart (dy, '1/29/1973 ')) ' –

+0

Cảm ơn! Đã sửa. ——————— – brianary

0

Tôi hy vọng điều này là hoàn hảo với điều kiện bạn chấp nhận thuật toán rằng một đứa bé nhảy bước một tuổi lớn hơn vào ngày 29 tháng 2, hoặc ngày 1 tháng 3 vào những năm không nhuận. @DOB phải chứa ngày trong vòng vài thế kỷ nay, @AsOf phải chứa ngày tương tự> = @DOB:

SET @Age = YEAR(@AsOf) - YEAR(@DOB) - 1 
IF MONTH(@AsOf) * 100 + DAY(@AsOf) >= MONTH(@DOB) * 100 + DAY(@DOB) 
    SET @Age = @Age + 1 

Tôi muốn REALLY REALLY đánh giá cao bất kỳ thử nghiệm và ý kiến ​​như tôi đã không tìm thấy một cách chưa phá vỡ nó ... được nêu ra.

Added - 2014/01/31: Cái này dường như làm việc một cách hoàn hảo quá mặc dù thoạt nhìn có vẻ quá thô:

SET @Age = FLOOR(DATEDIFF(dd,@DOB,@CompareDate)/365.25) 

Pop này trong một hàm và đây là một kịch bản thử nghiệm:

SELECT dbo.fnGetAge('2/27/2008', '2/27/2012') 
    SELECT dbo.fnGetAge('2/27/2008', '2/28/2012') 
    SELECT dbo.fnGetAge('2/27/2008', '2/29/2012') 
    SELECT dbo.fnGetAge('2/27/2008', '3/1/2012') 
    -- 4 4 4 4 
    SELECT dbo.fnGetAge('2/28/2008', '2/27/2012') 
    SELECT dbo.fnGetAge('2/28/2008', '2/28/2012') 
    SELECT dbo.fnGetAge('2/28/2008', '2/29/2012') 
    SELECT dbo.fnGetAge('2/28/2008', '3/1/2012') 
    -- 3 4 4 4 
    SELECT dbo.fnGetAge('2/29/2008', '2/27/2012') 
    SELECT dbo.fnGetAge('2/29/2008', '2/28/2012') 
    SELECT dbo.fnGetAge('2/29/2008', '2/29/2012') 
    SELECT dbo.fnGetAge('2/29/2008', '3/1/2012') 
    -- 3 3 4 4 
    SELECT dbo.fnGetAge('3/1/2008', '2/27/2012') 
    SELECT dbo.fnGetAge('3/1/2008', '2/28/2012') 
    SELECT dbo.fnGetAge('3/1/2008', '2/29/2012') 
    SELECT dbo.fnGetAge('3/1/2008', '3/1/2012') 
    -- 3 3 3 4 
    SELECT dbo.fnGetAge('3/1/2007', '2/27/2012') 
    SELECT dbo.fnGetAge('3/1/2007', '2/28/2012') 
    SELECT dbo.fnGetAge('3/1/2007', '2/29/2012') 
    SELECT dbo.fnGetAge('3/1/2007', '3/1/2012') 
    -- 4 4 4 5 
    SELECT dbo.fnGetAge('3/1/2007', '2/27/2013') 
    SELECT dbo.fnGetAge('3/1/2007', '2/28/2013') 
    SELECT dbo.fnGetAge('3/1/2007', '3/1/2013') 
    SELECT dbo.fnGetAge('2/27/2007', '2/28/2013') 
    SELECT dbo.fnGetAge('2/28/2007', '2/28/2014') 
    -- 5 5 6 6 7 

Chúc mừng

PS: Có thể bạn có thể chỉnh sửa quyết định ngày 29 tháng 2 trở về sớm hơn nếu thuyền trôi nổi.

0
SELECT Pname, DOB, DATEDIFF(YEAR, DOB, GETDATE()) AS Age 
FROM tablename 
+0

một chút giải thích có thể đi một chặng đường dài – davejal

Các vấn đề liên quan