2017-02-17 2 views
0

Я работаю с проектом в SSRSРасчет возраста из ССН

В базе данных у меня есть столбец с именем X, и в этой колонке, у меня есть номера социального обеспечения для всех работников и все номера выглядят, как это с любой из (- или /) примера 1111111111 (DDMMYYXXXX).

Вопрос в том, как я могу написать sql, чтобы выбрать только 6 первых чисел, а затем минус текущее время и в конце дать мне возраст сотрудников. Может кто-то, пожалуйста, назовите меня в правильном направлении. Спасибо.

До сих пор SQL я написал выглядеть следующим образом:

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()) 
+0

DATEDIFF (YEAR, CAST (LEFT (ColName, 6) AS DATE), GETDATE())) – Snowlockk

+0

LEFT (Users.SSN, 6), что делает это выглядит? – Snowlockk

+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; 
+0

Спасибо за все это, но у меня ошибка: неправильный синтаксис рядом с ключевым словом 'convert'. – RyaN

+0

Пропущенная запятая, см. Мой отредактированный ответ. –

+0

Я получаю еще один: конверсия не удалась при преобразовании даты и времени из строки символов – RyaN

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 как этот век. Что может быть проблемой для пожилых людей ...

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()) 
+0

не могли бы вы также написать запрос, я не совсем понимаю с UDF :) – RyaN

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