【发布时间】:2018-04-03 19:21:09
【问题描述】:
希望您度过了一个宁静的复活节。感谢您是否可以在以下方面为我提供建议/帮助。 (使用函数/不使用函数)
下面是我的数据集,期望的输出(使用规则中的 DOB 规范导出年龄)
需要您的帮助(请注意,我在 MSSQL 环境中寻找解决方案):-
1. 提出年龄字段。(我尝试了以下脚本,但它没有工作,因为它不够动态,无法包含所有 DOB 规则,我还附上了一个 oracle 脚本,它可以作为供大家参考)
SELECT
[ID],
[DOB],
'age' = DATEDIFF(HOUR,(CONVERT(date,(CASE WHEN ([DOB] like '99/%/%') THEN (REPLACE([DOB],'99','01'))
ELSE [DOB] END),103)),GETDATE())/8766
from [Sample]
Sample_Dataset
create table Sample (
Id Varchar (50),
DOB Varchar (50))
insert into Sample(Id, DOB)
Values
('38603', '24/02/1969'),
('38605', '22/09/1969'),
('36356', '17/03/1954'),
('36374', '17/05/1975'),
('36441', '17/08/1961'),
('1a', '10/05/9999'),
('1b', '10/99/9999'),
('1c', '99/99/9999'),
('2a', '--/--/1935'),
('2b', '00/00/1935'),
('2c', '88/88/1935'),
('2d', '99/99/1935'),
('3a', '10/--/1935'),
('3b', '10/00/1935'),
('3c', '10/88/1935'),
('3d', '10/99/1935'),
('4a', '--/09/1935'),
('4b', '00/09/1935'),
('4c', '88/09/1935'),
('4d', '99/09/1935')
期望的输出
身份证 |出生日期 |年龄(截至 05-03-2018; dd-mm-yyyy) 38603 | 1969 年 2 月 24 日 | 49——一切皆知 38605 | 22/09/1969 | 48 36356 | 1954 年 3 月 17 日 | 63 36374 | 1975 年 5 月 17 日 | 42 36441 | 1961 年 8 月 17 日 | 56 1a | 10/05/9999 |null -- 未知年份 1b | 10/99/9999 |空 1c | 99/99/9999 |空 2a | --/--/1935 |82 --未知的日期和月份 2b | 00/00/1935 |82 2c | 1935 年 88 月 88 日 |82 二维 | 99/99/1935 |82 3a | 10/---/1935 |82 --未知月份但已知年份 3b | 1935 年 10 月 00 日 |82 3c | 1935 年 10 月 88 日 |82 3d | 1935 年 10 月 99 日 |82 4a | --/09/1935 |82 --未知日期但已知月份 4b | 00/09/1935 |82 4c | 1935 年 9 月 88 日 |82 4d | 1935 年 9 月 99 日 |82规则:- 正如您在 cmets 中的上述 5 个场景 中看到的那样
- 一切都是已知的(使用规定的出生日期计算年龄)
- 未知的年份(将年龄设为null,因为年份是已知的)
- 未知的日期和月份(使用 01/07 表示未知的 dd/mm 和声明的 yyyy)
- 未知的月份但已知的日期(使用 07 表示未知的 mm 和规定的 dd/07/yyyy)
- 未知的日期但已知的月份(使用 15 表示未知的 dd 和规定的 15/mm/yyyy)
Oracle 中的解决方案
首先创建一个函数(尝试在T-SQL中复制这个逻辑但不成功,因此我在这里)
create or replace function check_dt(in_date in VARCHAR2, in_format in VARCHAR2 default 'DD/MM/YYYY')
RETURN NUMBER
IS
V_DATE DATE;
V_STATUS INTEGER;
BEGIN
SELECT TO_DATE(in_date,in_format)
INTO V_DATECASE
FROM DUAL;
V_STATUS := 0;
RETURN V_STATUS;
EXCEPTION WHEN OTHERS THEN
V_STATUS := SQLCODE;
RETURN V_STATUS;
END;
select check_dt('11/30/2017') from dual;
select TO_DATE('15/--/9999','DD/MM/YYYY') from dual;
select id, dob,
case when check_dt(dob) = -1843 --not valid month, default it to July (07)
THEN substr(dob,1,2)||'/07'||substr(dob,7,4)
when check_dt(dob) = -01847 -- day of month must between 1 and last day of month
THEN '1/07/'||substr(dob,7,4)
WHEN check_dt(dob) = 0 and to_date(dob,'dd/mm/yyyy') > sysdate
THEN NULL
WHEN check_dt(dob) = -0183 -- date not valid for month
THEN '15/'||substr(dob,4)
ELSE
THEN dob
END New_dob
from SAMPLE;
任何帮助将不胜感激。 非常感谢。
【问题讨论】:
-
mysqlsql-server。mysql不使用tsql。你能相应地更新你的标签吗? -
@Larnu:感谢您的关注。我在想mssql。没有正确阅读。再次感谢。
标签: sql sql-server database tsql