Sql server 从SSN计算年龄
我在SSRS的一个项目中工作 在数据库中,我有一个名为X的列,在这个列中,我有所有员工的社会保险号码,所有号码都是这样的,没有任何-或/例如1111111111 DDMMYYXXXX 我的问题是,我如何编写一个sql,只选择6个第一个数字,然后减去当前时间,最后给出员工的年龄。谁能给我指一下正确的方向吗。 谢谢 到目前为止,我编写的sql如下所示:Sql server 从SSN计算年龄,sql-server,reporting-services,Sql Server,Reporting Services,我在SSRS的一个项目中工作 在数据库中,我有一个名为X的列,在这个列中,我有所有员工的社会保险号码,所有号码都是这样的,没有任何-或/例如1111111111 DDMMYYXXXX 我的问题是,我如何编写一个sql,只选择6个第一个数字,然后减去当前时间,最后给出员工的年龄。谁能给我指一下正确的方向吗。 谢谢 到目前为止,我编写的sql如下所示: create function dbo.birthdate_from_cpr(@cpr varchar(10)) returns date as b
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 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())
convert(date, substring(Users.SSN , 17, 2) + substring(Users.SSN , 15, 2) + substring(Users.SSN , 13, 2), 12)
一种方法是使用和创建一个格式良好的字符串,并将其更改为日期值,然后就可以了
不要担心查询的长度,它只是您需要的最后一列。我选择在不同的专栏中展示每一步
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;
您需要从ssn列中提取日期以计算年龄,假设您的格式为1111111 DDMMYYXXXX。但是格式字符串DDMMYY本身不容易转换,因此我们需要将其转换为函数可以识别的格式 大概是这样的:
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 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())
convert(date, substring(Users.SSN , 17, 2) + substring(Users.SSN , 15, 2) + substring(Users.SSN , 13, 2), 12)
从那时起,这是一件简单的事情
请注意,SQL Server将把00到49年视为本世纪。对于老年人来说,这可能是一个问题……我建议创建一个UDF,将CPR转换为一个日期,这将使您的生活在未来更容易进行分析,并且您可以更轻松地进行测试。这个版本解决了@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())
DATEDIFFYEAR,CASTLEFTcolName,6 AS DATE,GETDATELEFTUsers.SSN,6这是什么样子的?您可以共享示例表数据和预期的输出。DATEDIFFYEAR,CONVERTDATE,CONVERTVARCHAR10,LEFTUsers.SSN,6,GETDATE试试这个。这可能是一个括号问题,但这是否是一个安全的假设,即没有员工超过100人?感谢所有这些,但我得到了错误:关键字“convert”附近的语法不正确。我得到了另一个错误:从字符串转换日期和时间时转换失败。您确定它是ddmmyy吗?我没有您的示例数据可供使用,这就是我自己创建示例数据的原因。列的实际长度是不相关的,只要它至少有6个字符长,因为我们只对前6个字符感兴趣。0101012342转换为2001年1月1日。表中至少有一个数字不能转换为ddmmyy。如果您使用的是2012版本或更高版本,请将转换替换为try_convert,并查看从何处获得空值。这些是无法转换的数字。也许空值就是问题所在。我已经编辑了我的答案以忽略空值。请您也写一个查询,我不太理解UDF: