从SSN计算年龄

时间:2017-02-17 09:25:44

标签: sql-server reporting-services

我正在使用SSRS中的项目

在数据库中,我有一个名为X的列,在此列中,我有所有员工的社会安全号码,所有数字看起来都是这样的( - 或/)示例1111111111(DDMMYYXXXX)。

我的问题是,如何编写一个sql来选择6个第一个数字然后减去当前时间,最后给我一个员工年龄。有人可以指出我正确的方向。 感谢。

到目前为止,我写的sql看起来像这样:

{{1}}

3 个答案:

答案 0 :(得分:1)

一种方法是使用leftstuff创建格式正确的字符串,然后convert将其更改为日期值,然后只需datediff

不要被查询的长度惊吓,它只是你需要的最后一列。我选择在不同的专栏中展示每一步。

DECLARE @SSN char(10) = '1309761234'

SELECT  @SSN as OriginalString,
        STUFF(
             STUFF(LEFT(@SSN, 6), 3, 0, '.')
            , 6, 0, '.') As DateString,
       CONVERT(date, 
               STUFF(
                     STUFF(LEFT(@SSN, 6), 3, 0, '.')
               , 6, 0, '.')
       , 4) As Date, -- German, no century - dd.mm.yy
        DATEDIFF(YEAR, 
                    CONVERT(date, 
                            STUFF(LEFT(@SSN, 4), 3, 0, '.') +'.'+
                            CAST(DATEPART(YEAR, GETDATE()) / 100 - 1 as char(2)) + 
                            SUBSTRING(@SSN, 5, 2)
                    , 104) 
                 , GETDATE()) As Age

结果:

OriginalString  DateString  Date                    Age
1309761234      13.09.76    13.09.1976 00:00:00     41

使用您的查询:

SELECT Users.Id, Users.FirstName + ' ' + Users.LastName AS Medarbajder,
Users.SSN AS CPRNR, 
CASE WHEN Users.SSN IS NOT NULL THEN
DATEDIFF(YEAR, 
        CONVERT(date, 
                            STUFF(LEFT(Users.SSN, 4), 3, 0, '.') +'.'+
                            CAST(DATEPART(YEAR, GETDATE()) / 100 - 1 as char(2)) + 
                            SUBSTRING(Users.SSN, 5, 2)
                    , 104) 
, GETDATE()) 
ELSE
NULL
END As Age,
convert(varchar(10), Paychecks.WorkStartDate, 105) AS StartDato ,
Paychecks.DepartmentName AS Afdelinger

FROM dbo.Paychecks, dbo.Users
WHERE Users.CustomerId=214 AND Users.Id=Paychecks.UserId order by Users.FirstName;

答案 1 :(得分:0)

您需要从ssn列中提取日期以计算年龄,假设您描述的格式为" 1111111111(DDMMYYXXXX)"。但是格式字符串DDMMYY不能轻易地自行转换,因此我们需要将其翻转为CONVERT函数将识别的格式

这样的事情:

convert(date, substring(Users.SSN , 17, 2) + substring(Users.SSN , 15, 2) + substring(Users.SSN , 13, 2), 12)

从那里简单到DATEDIFF年龄。

请注意,SQL Server将把00年到49年视为本世纪。这可能是老年人的一个问题...

答案 2 :(得分:0)

我建议创建一个UDF,用于将CPR转换为date,这样可以让您在将来进行分析时更轻松,并且您可以更轻松地进行测试。这个版本解决了@ paul-bambury假设没有人超过100岁的世纪问题。

create function dbo.birthdate_from_cpr(@cpr varchar(10))
returns date
as
begin
  declare @year char(2) = substring(@cpr, 5, 2),
          @month char(2) = substring(@cpr, 3, 2),
          @day char(2) = substring(@cpr, 1, 2),
          @century char(2)

  -- if the current 2 digit year is less than the birthday year, assume it was last century
  -- e.g. 76 should be 1976 but 02 should be 2002
  if right(datepart(yy, getdate()), 2) < @year
    set @century = left(datepart(yy, getdate()) - 100, 2)
  else
    set @century = left(datepart(yy, getdate()), 2)


  return convert(date, @century + @year + @month + @day, 120)
end
go

select dbo.birthdate_from_cpr('1312761234'),
       dbo.birthdate_from_cpr('0101041234'),
       age = datediff(yy, dbo.birthdate_from_cpr('1312761234'), getdate())