2012-03-16 87 views
1

可能重复:
How to calculate age in T-SQL with years, months, and days计算和显示SQL Server上的年龄为列(XX年,XX个月)

我与SQL Server 2005在我年龄计算问题有一个客户表,其日期为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

我认为你应该考虑与该解决方案的本地化问题(和不同的标准来计算不同国家的年龄)。如果您不在意,您可能会:

+0

谢谢,我刚转换我的C#代码到我在我的视图中使用的SQL函数。 – EngAbth9 2012-03-17 19:02:45

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 2012-03-17 19:11:12

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 2012-03-17 19:07:04

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 server management studio上执行查询时显示此错误。 消息139,级别15,状态1,过程format_age,行0 无法将默认值分配给局部变量。 消息137,级别15,状态2,过程format_age,行10 必须声明标量变量“@years”。 消息139,级别15,状态1,过程format_age,行0 无法将默认值分配给局部变量。 消息137,级别15,状态2,过程format_age,行13 必须声明标量变量“@months”。 消息137,级别15,状态2,过程format_age,行15 必须声明标量变量“@years”。 – EngAbth9 2012-03-17 19:04:21

+0

在SQL Server 2008中引入了使用'DECLARE'语句赋值。我更新了答案,将其分解为单独的'DECLARE'和'SET'。 – 2012-03-17 22:22:38

+0

测试SQL Server 2000,它似乎工作。 – 2012-03-17 22:36:21