2012-03-16 4 views
1

Возможные Дублировать:
How to calculate age in T-SQL with years, months, and daysРасчет и показывая Возраст Колонка на Sql Server, как (хх лет, хх месяцев)

У меня есть проблема с подсчетом возраста на Sql Server 2005. I иметь таблицу клиентов, которая имеет дату birth column. Я хочу создать представление, которое имеет age column, и это age column должно показать возраст person, вычитая дату рождения с сегодняшнего дня (довольно просто).

Я нашел здесь несколько хороших ресурсов, но я хочу точно показать возраст по годам и месяцам. например (47 лет, 3 месяца). Это означает, что я хочу иметь как значения года, так и месяца, и я хочу добавить string (либо 'years', 'yrs', 'y', 'months', 'mon', 'm', ...) в соответствующее значение, и отобразить его, например. (25 years, 2 months). И если возраст человека составляет, например, 3 months, он должен отображать '3 months', а не '0 years, 3 months '.

Если возраст человека составляет несколько лет без каких-либо месяцев, он должен отображаться, например. «5 years» не '5 years, 0 months '

О, я уже сделал это с помощью C#, но я хочу, чтобы создать столбец на представлении SQL, так что я могу просто заполнить мой GridView с помощью представления, не делая расчет на мой C# код. Если это помогает, я могу опубликовать свой код C# здесь.

ответ

0

Я думаю, вы должны рассмотреть проблемы локализации с этим решением (и различные стандарты для расчета возраста в разных странах). Если вас это не волнует, вы можете:

  • Напишите скалярную функцию SQL для расчета возраста (см. these posts on MSDN).
  • Напишите функцию C# и интегрируйте ее в SQL Server (см. this article on SQLTeam).
+0

Спасибо, я просто конвертируются мой C# код на Sql функцию, которую я использовал в своем представлении. – EngAbth9

0

Вам нужно что-то вроде этого:

SELECT *, 
    case when DATEDIFF(MONTH, Birthday, GETDATE()) < 12 
    then 
    CONVERT(nvarchar(16), DATEDIFF(MONTH, Birthday, GETDATE())) + ' months' 
    else 
    CONVERT(nvarchar(16), DATEDIFF(YEAR, Birthday, GETDATE())) + ' years, ' + 
    CONVERT(nvarchar(16), DATEDIFF(MONTH, Birthday, GETDATE()) % 12) + ' months' 
    end 
FROM dbo.CUSTOMER 
+0

Это был хороший, но иногда он дает неправильные ответы. – EngAbth9

0

Может быть что-то вроде этого:

Тестовые данные

DECLARE @tbl TABLE(birthDay DATETIME) 
INSERT INTO @tbl 
VALUES 
    ('2004-04-05'), 
    ('2001-02-05') 

Запрос

;WITH Years 
AS 
( 
    SELECT 
     DATEDIFF(yy, tbl.birthDay, GETDATE()) - CASE WHEN (MONTH(tbl.birthDay) > MONTH(GETDATE())) OR (MONTH(tbl.birthDay) = MONTH(GETDATE()) AND DAY(tbl.birthDay) > DAY(GETDATE())) THEN 1 ELSE 0 END AS Years, 
     tbl.birthDay 
    FROM 
     @tbl AS tbl 
), BithDayWithMonth 
AS 
(
    SELECT 
     Years.Years, 
     DATEDIFF(m, years.tmp, GETDATE()) - CASE WHEN DAY(Years.birthDay) > DAY(GETDATE()) THEN 1 ELSE 0 END AS Months 
    FROM 
     (
      SELECT 
       DATEADD(yy, Years.Years, Years.birthDay) AS tmp, 
       Years.Years, 
       Years.birthDay 
      FROM 
       Years 
     ) AS years 
) 
SELECT 
    (CASE WHEN BithDayWithMonth.Years=0 THEN '' ELSE CAST(BithDayWithMonth.Years AS VARCHAR(10))+' years' END)+ 
    (CASE WHEN BithDayWithMonth.Months=0 THEN '' ELSE (CASE WHEN NOT BithDayWithMonth.Years=0 THEN ', ' ELSE '' END) + 
    CAST(BithDayWithMonth.Years AS VARCHAR(10))+' months' END) 
FROM 
    BithDayWithMonth 
+0

Запрос выполняется успешно, но есть некоторые нерегулярные значения, такие как 24 года, 24 месяца (с использованием 3/17/2012 как сейчас и 3/20/1987 как дата рождения) – EngAbth9

0
CREATE FUNCTION format_age(
    @DOB datetime, 
    @now datetime 
) 
RETURNS nvarchar(30) 
BEGIN 
    DECLARE @years int, @months int; 
    IF @DOB > @now RETURN N'not born yet'; 
    SET @years = DATEDIFF(year, @DOB, @now); 
    IF MONTH(@DOB) * 100 + DAY(@DOB) > MONTH(@now) * 100 + DAY(@now) 
     SET @years = @years - 1; 
    SET @months = DATEDIFF(month, DATEADD(year, @years, @DOB), @now); 
    IF DAY(@DOB) > DAY(@now) 
     SET @months = @months - 1; 
    RETURN CASE 
     WHEN @years = 0 THEN CONVERT(nvarchar(30), @months) + N' months' 
     WHEN @months = 0 THEN CONVERT(nvarchar(30), @years) + N' years' 
     ELSE CONVERT(nvarchar(30), @years) + N' years, ' + 
      CONVERT(nvarchar(30), @months) + N' months' 
    END; 
END 
GO 
SELECT '2011-02-16' as dt, dbo.format_age('2011-02-16', '2012-03-16') as age 
UNION 
SELECT '2011-03-16', dbo.format_age('2011-03-16', '2012-03-16') 
UNION 
SELECT '2011-03-17', dbo.format_age('2011-03-17', '2012-03-16') 
UNION 
SELECT '2012-03-16', dbo.format_age('2012-03-16', '2012-03-16') 
UNION 
SELECT '2012-03-17', dbo.format_age('2012-03-17', '2012-03-16') 
dt   age 
2011-02-16 1 years, 1 months 
2011-03-16 1 years 
2011-03-17 11 months 
2012-03-16 0 months 
2012-03-17 not born yet 

Ссылка дата 2012-03-16

+0

показывает эту ошибку при выполнении запроса на студию управления сервером sql. Msg 139, Level 15, State 1, Procedure format_age, Line 0 Невозможно присвоить значение по умолчанию локальной переменной. Msg 137, Level 15, State 2, Procedure format_age, Строка 10 Должен объявить скалярную переменную «@years». Msg 139, Level 15, State 1, Procedure format_age, Line 0 Невозможно присвоить значение по умолчанию локальной переменной. Msg 137, Level 15, State 2, Procedure format_age, Строка 13 Должен объявить скалярную переменную «@months». Msg 137, Level 15, State 2, Procedure format_age, Строка 15 Должен объявить скалярную переменную «@years». – EngAbth9

+0

Назначение значения с помощью оператора 'DECLARE' было представлено в SQL Server 2008. Я обновил ответ, чтобы разделить его на отдельные' DECLARE' и 'SET'. –

+0

Протестировано на SQL Server 2000, и, похоже, оно работает. –

Смежные вопросы