身份证的标准化处理sql怎么写

求各位有识之士,身份证标准化处理的sql语句应该怎么写,需求如下图

img

前两行比较好处理:

case when length(trim(id_no))<>15 then upper(id_no)
         when length(trim(id_no))=15 then concat(substr(trim(id_no),1,6),'19',substr(trim(id_no),7)) end

第四行也可以直接写:

case when trim(id_no) REGEXP '[^0-9.]'=1 then id_no

第三行的需求只通过一句sql应该是不太好写的,因为涉及到了对一个字符串进行依次遍历,取出里面的数字,这可能需要自己创建函数或者写一个存储过程才能实现这个功能了

1、首先,需求中有两个问题:
一个是:15号的身份证号 + ‘19’是两位长,而除11的余数可能为10,也是两位长,所以最终的身份证号可能是19位长;
另一个是:最后一句话,是输出加了“19”的身份证号还是原始的身份证号,未说清楚(我暂时就输出原始的数据了)
2、其次,我不明白“加权求和”是个啥算法,我只能按求和来处理了
3、解决方法也很简单,一个是判定字符长度(这个所有数据库都支持),另一个是正则表达式判定所有均只含0-9,这个绝大部分数据库都支持,再就是重复劳动提取各个数字并转换为int相加而已……我就以PostGresQL数据库为例给出解决方案:(其他数据库自行对照转换即可):


WITH t AS (
    SELECT * FROM ( VALUES( '511111200101013333' ), ( '51111120010101333a' ), ( '511111800101222' ), ( '511a11800101222' ) ) AS t( sfzh ) )
SELECT sfzh
      , ( CASE WHEN length( sfzh ) != 15 THEN upper( sfzh )
               WHEN sfzh ~ '^[0-9]{15}$' THEN LEFT( sfzh, 5 ) || '19' || RIGHT( sfzh, 10 )
                 || ( substr( sfzh,  1, 1 )::int + substr( sfzh,  2, 1 )::int + substr( sfzh,  3, 1 )::int + substr( sfzh,  4, 1 )::int + substr( sfzh,  5, 1 )::int
                    + substr( sfzh,  6, 1 )::int + substr( sfzh,  7, 1 )::int + substr( sfzh,  8, 1 )::int + substr( sfzh,  9, 1 )::int + substr( sfzh, 10, 1 )::int
                    + substr( sfzh, 11, 1 )::int + substr( sfzh, 12, 1 )::int + substr( sfzh, 13, 1 )::int + substr( sfzh, 14, 1 )::int + substr( sfzh, 15, 1 )::int + 10 ) % 11
               ELSE sfzh END ) sfzh1
  FROM t;

输出结果(sfzh1字段为需求结果):

img

代码特别说明:sfzh ~ '^[0-9]{15}$' 表示正则匹配,^表示以[0-9]任一数字开始,{15}表示全部为[0-9]任一数字共15位长,$表示字符串结束

没懂第三个啥意思
with t1 as (
select '511111200101013333' sfz union
select '51111120010101333a' sfz union
select '511111800101222' sfz union
select '511a11800101222' sfz )
select case when length(sfz)!=15 then upper(sfz)
when length(sfz)=15 then concat(concat(substr(sfz,1,6),'19'),substr(sfz,6))
when sfz not regexp '[a-k]' then concat(sfz,floor(sfz/11))
when sfz regexp '[a-k]' then sfz
end sfz1
,length(sfz)
,sfz
,floor(sfz/11)
from t1