我正在使用SSRS中的项目
在数据库中,我有一个名为X的列,在此列中,我有所有员工的社会安全号码,所有数字看起来都是这样的( - 或/)示例1111111111(DDMMYYXXXX)。
我的问题是,如何编写一个sql来选择6个第一个数字然后减去当前时间,最后给我一个员工年龄。有人可以指出我正确的方向。 感谢。
到目前为止,我写的sql看起来像这样:
{{1}}
答案 0 :(得分:1)
一种方法是使用left
和stuff
创建格式正确的字符串,然后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())