• 【hive】异常日期查找


    1.日期转化为时间戳

    只取前面符合日期格式的内容转为时间戳,超出格式的部分忽略,少于格式则格式不符合,date_format也是一样的

    1. select unix_timestamp('2022-2-2', 'yyyy-MM-dd') = unix_timestamp('2022-2-2-2', 'yyyy-MM-dd') --true
    2. select unix_timestamp('2022-2', 'yyyy-MM-dd') --null

    2.正则表达式

    regexp和rlike一样,rlike与like不同的是可以匹配正则表达式

    (1)位置匹配:
    (^) 表示匹配字符串的开始,空值:^$
    ($) 表示匹配字符串的结束

    ^或者$写一个就够了

    (2)元字符匹配
    (.)   表示匹配除换行符以外的任意字符。
    (\w) 表示匹配字母、下划线、数字或汉字(\\W)。
    (\d) 表示匹配数字
    (\s) 表示匹配任意的空白符
    ([ ])  表示匹配方括号中任一字符
    ([^匹配内容]) 表示不匹配方括号中任一字符

    ({ })重复几次

    匹配日期:

    1. //限制格式:XXXX-X(X)-X(X)
    2. select birthday not rlike '^\\d{4}-\\d{1,2}-\\d{1,2}$'
    3. //限制格式:19(或者20)XX-XX-XX(月、日)在正常范围内
    4. select birthday not rlike '([1][9]|[2][0])([0-9]{2})-([1-9]|(0[1-9])|1[0-2])-([1-9]|(0[1-9])|([1-2][0-9])|30|31)$'

    3.split、size

    split可以切分日期,返回的是数组形式,可以取某一个的元素,split(birthday, '-')[0]

    用size可以获取这个数组大小,也就可以判断是否符合日期格式

    4.总体思路

    日期为空值(null)或者空都是正常,其他为异常

    分为四种情况考虑:

    1. 按 '-' 切分得到的切分数不为3
    2. 不符合规定的正则表达式,年份做了一点限制;月份和日限制在正常范围,但是有些月没有31号,需要之后再限制
    3. 月和日不符合正常日期,把有些月没有31号的情况等做限制

    5.优化

    分的情况分别做交叉,a left join b where a.accountname is null

    两个数据集理论上存在几种关系
    1, 没关系
    2,部分包含(交集)
    3,全包含(子集)

    如果存在子集 ,子集对应的条件就能被替代掉。

    这里切分数那种情况可以去掉,因为第二种情况已经确定好切分数是3了

    1. with tmp1 as (
    2. select accountname, birthday
    3. from xsj_acc_real_identity_en
    4. where dt = '2022-07-10'
    5. and birthday is not null
    6. and birthday != ''
    7. and size(split(birthday, '-')) = 3
    8. and birthday not rlike '([1][9]|[2][0])([0-9]{2})-([1-9]|(0[1-9])|1[0-2])-([1-9]|(0[1-9])|([1-2][0-9])|30|31)$'
    9. ),
    10. tmp2 as (
    11. select accountname, birthday
    12. from xsj_acc_real_identity_en
    13. where dt = '2022-07-10'
    14. and birthday is not null
    15. and birthday != ''
    16. and size(split(birthday, '-')) = 3
    17. and unix_timestamp(date_format(birthday, 'yyyy-MM-dd'), 'yyyy-MM-dd') != unix_timestamp(birthday, 'yyyy-MM-dd')
    18. ),
    19. tmp3 as (
    20. select accountname, birthday
    21. from xsj_acc_real_identity_en
    22. where dt = '2022-07-10'
    23. and birthday is not null
    24. and birthday != ''
    25. and size(split(birthday, '-')) = 3
    26. and split(birthday, '-')[0] not between 1900 and 2022
    27. )
    28. select tmp3.birthday
    29. from tmp3
    30. left join tmp2
    31. on tmp2.accountname = tmp3.accountname
    32. where tmp2.accountname is null;
    33. select birthday
    34. from xsj_acc_real_identity_en
    35. where dt = '2022-07-10'
    36. and birthday is not null
    37. and birthday != ''
    38. and size(split(birthday, '-')) = 3
    39. and (
    40. birthday not rlike '([1][9]|[2][0])([0-9]{2})-([1-9]|(0[1-9])|1[0-2])-([1-9]|(0[1-9])|([1-2][0-9])|30|31)$'
    41. or split(birthday, '-')[0] not between 1900 and 2022
    42. )

  • 相关阅读:
    C++ -- 学习系列 static 关键字的使用
    java计算机毕业设计ssm气象百事通系统-天气预报系统
    C++实现单链表
    html5期末大作业:自适应网站开发——公司网站7页 ,响应式页面
    LVGL库入门教程 - 颜色和图像
    期货价值计算方法(期货的价值怎么计算)
    Java+JSP+Mysql+Tomcat实现Web图书管理系统
    什么是边缘计算网关?
    从零用VitePress搭建博客教程(6) -– 第三方组件库的使用和VitePress搭建组件库文档
    c++11知识:auto类型推导
  • 原文地址:https://blog.csdn.net/weixin_43955488/article/details/125891639