当前位置: 首页 > news >正文

【maxcompute|ODPS|SQL|HSQL】日期数据非标准日期格式(yyyy/M/d),如何转为yyyy-MM-dd HH:mm:ss标准格式

SQL中的日期数据转换真是一个复杂多变的问题啊!

一、需求及问题描述

在日常开发中,我们会遇到时间戳与标准日期格式之间的转换,两个日期差,及日期加加减减,想必大家都已经非常熟悉了

题主最近接到一个需求:

业务方给我一个表格,其中有一个截止日期字段
要求:
给定截止日期,查询截止日期前六个月的信息

但是Excel表格里面的日期是这样子的
在这里插入图片描述
把这些数据导入到ODPS中(题主是用阿里云的ODPS开发的),导入数据建表是,该截止日期字段是STRING类型的

SELECT deadline FROM case_3;

由下图可见,导入之后日期格式仍然不是标准日期格式
在这里插入图片描述
如果我想查询截止日期在2024/9/1号之前6个月内的数据应该怎样限制日期呢?
应当是

time <= deadline and time >= deadline-6个月

我们先直接查一下,结果为true,说明time <= deadline这端是没问题的,阿里云的Maxcompute会自动转换类型进行加减,这是阿里云底层的优化

SELECT '2024-08-28 18:39:34'<'2024/9/1';

在这里插入图片描述
但是,我们再查下面的SQL,得到如下结果。显然,这并不符合我们本意。使用了ADD_MONTHS函数之后我们期望得到2024/6/1,这样才能与'2024-08-28 18:39:34'作对比。这篇文章主要介绍如何解决这个问题。

SELECT ADD_MONTHS('2024/9/1',-6),'2024-08-28 18:39:34'>ADD_MONTHS('2024/9/1',-6);

在这里插入图片描述

二、ADD_MONTH函数的用法

我在这里总结一下它的用法:

add_months函数需要接收两个参数
1、第一个参数是开始日期,它的数据类型可以是date|datetime|timestamp|string这些类型中的一个,datedatetimestring类型有对应的格式要求
2、第二个参数是一个整型的数字,用来表示加多少个月。

返回的数据类型是string类型的,格式为yyyy-mm-dd。

详情见下面的介绍

命令格式

string add_months(date|datetime|timestamp|string <startdate>, int <num_months>)

参数说明

startdate:必填。DATE、DATETIME、TIMESTAMP或STRING类型,格式为yyyy-mm-dd、yyyy-mm-dd
hh:mi:ss或yyyy-mm-dd

hh:mi:ss.ff3。取值为STRING类型格式时,至少要包含yyyy-mm-dd且不含多余的字符串。

num_months:必填。INT型数值。

返回值说明

返回开始日期startdate增加num_months个月后的日期,返回STRING类型的日期值,格式为yyyy-mm-dd。返回规则如下:

startdate非DATE、DATETIME、TIMESTAMP或STRING类型,或格式不符合要求时,返回NULL。

startdate值为NULL时,返回报错。

num_months值为NULL时,返回NULL。

三、格式化2024/9/1到2024-09-01

知道add_months函数的用法之后,我们现在面临的问题是,如何把不规范的日期规范。
注意:此时DATE_FORMAT函数已经不再适用,因为DATE_FORMAT的入参不支持接受2024/9/1格式的数据

string date_format(date|timestamp|string <date>, string <format>)

参数说明

date:必填。待转换的日期值。支持DATE、TIMESTAMP或STRING类型。

DATE和STRING类型只能在Hive兼容模式下使用,您可以执行set
odps.sql.hive.compatible=true;命令打开Hive模式。

如果参数为STRING类型,则格式只支持以下三种日期字段:

‘yyyy-MM-dd’,例如’2019-12-27’。

‘yyyy-MM-dd hh:mm:ss’,例如’2019-12-27 12:23:10’。

‘yyyy-MM-dd hh:mm:ss.SSS’,例如’2019-12-27 12:23:10.123’。

format:必填。STRING类型常量。format可由如下日期字段组成,例如yyyy-MM-dd
hh:mm:ss.SSS或yyyy-MM-dd hh:mi:ss.SSS:

解决方案

补齐日期中缺失的位数,并把它转化为标准日期格式。
废话不多说,直接贴出来SQL,标准化之后的数据如下图所示,符合我们的预期:

SELECT  deadline,CONCAT(-- 年份  SPLIT(deadline,'/')[0],'-',-- 月份,确保两位  LPAD(SPLIT(deadline,'/')[1],2,'0'),'-',-- 日,确保两位  LPAD(SPLIT(deadline,'/')[2],2,'0'),' 00:00:00') AS formatted_date
FROM    case_3
;

在这里插入图片描述

这里着重介绍一下LPAD函数:

当需要格式化数据表中的字符串,以保证字符串输出的一致性和对齐时,使用LPAD函数,用字符串str2将字符串str1向左补足到length位。

总结一下它的用法:
LPAD函数接收三个参数

第一个参数为string类型,为需要补齐的字符串
第二个参数为Int类型,表示该字符串补齐后需要达到的长度或者位数
第三个参数为string类型,为长度不足时,使用该字符串补齐
返回类型为string类型

详情见下面的介绍

命令格式

string lpad(string <str1>, int <length>, string <str2>)

参数说明

str1:必填。STRING类型。待向左补位的字符串。

length:必填。INT类型。补位后的目标位数。

str2:必填。用于补位的字符串。

返回值说明

返回STRING类型。返回规则如下:

如果length小于str1的位数,则返回str1从左开始截取length位的字符串。

如果length为0,则返回空串。

如果没有输入参数或任一输入参数值为NULL,返回NULL。

如果length大于str1的位数且小于str1和str2的位数之和,则按照str2字符从左到右的顺序将str1字符串向左补足到length位。

我们来解释一下这段SQL


-- SPLIT(deadline,'/')[0] 使用'/切分字符串',使其转化为一个数组,取数组第0位数据,即年(yyyy)所在的位置,年份不需要补齐
--  LPAD(SPLIT(deadline,'/')[1],2,'0') 使用'/切分字符串',使其转化为一个数组,取数组第1位数据,即月(MM)所在的位置,月份需要向左补齐为两位,缺失的位数用0补齐
-- LPAD(SPLIT(deadline,'/')[2],2,'0')  使用'/切分字符串',使其转化为一个数组,取数组第2位数据,即日(dd)所在的位置,日需要向左补齐为两位,缺失的位数用0补齐
-- 使用concat函数将年月日用'-'拼接,并给它拼接上时分秒
SELECT  deadline,CONCAT(-- 年份  SPLIT(deadline,'/')[0],'-',-- 月份,确保两位  LPAD(SPLIT(deadline,'/')[1],2,'0'),'-',-- 日,确保两位  LPAD(SPLIT(deadline,'/')[2],2,'0'),' 00:00:00') AS formatted_date
FROM    case_3
;

想必到这里各位读者已经很清楚了。
LPAD函数不仅在ODPS中可以使用,在hive中也有此函数,各位读者只需要注意入参的格式和数据类型即可。

除了LPAD函数,同样有RPAD函数,用法和LPAD一样,只不过它是向右补齐字符串到指定长度。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 基于约束大于规范的想法,封装缓存组件
  • sqlite3的db.interrupt方法深入解析
  • 台球助教APP小程序的前端交互设计
  • error:0308010C:digital envelope routines::unsupported【超详细图解】
  • 【C# ASP.NET Vue】没想到吧!怀旧小筑客栈管理系统可以这样高效,集成MySQL数据库,一键管理客房,预订不再是难题
  • 9月3日复盘日记
  • OpenCV绘图函数(12)绘制直线函数 line()的使用
  • cpu架构:x86和arm
  • 差分传输与单端传输
  • SIP,VOIP状态码详解
  • DataWhale AI夏令营-《李宏毅深度学习教程》笔记-task3
  • SQL【2】稍稍进阶
  • 第四届先进制造技术与电子信息国际学术会议(AMTEI 2024)
  • RedisTemplate集成+封装RedisUtil
  • 使用golang的AST编写定制化lint
  • 11111111
  • android 一些 utils
  • golang中接口赋值与方法集
  • JAVA_NIO系列——Channel和Buffer详解
  • ucore操作系统实验笔记 - 重新理解中断
  • Vue小说阅读器(仿追书神器)
  • 彻底搞懂浏览器Event-loop
  • 初识 beanstalkd
  • 从伪并行的 Python 多线程说起
  • 解决iview多表头动态更改列元素发生的错误
  • 如何在 Tornado 中实现 Middleware
  • 入门级的git使用指北
  • 因为阿里,他们成了“杭漂”
  • 云大使推广中的常见热门问题
  • ​iOS实时查看App运行日志
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (一)Neo4j下载安装以及初次使用
  • (转)详解PHP处理密码的几种方式
  • *** 2003
  • .Net 4.0并行库实用性演练
  • .Net CF下精确的计时器
  • .net dataexcel winform控件 更新 日志
  • .NET 命令行参数包含应用程序路径吗?
  • .NET导入Excel数据
  • .net访问oracle数据库性能问题
  • .net使用excel的cells对象没有value方法——学习.net的Excel工作表问题
  • @Autowired 与@Resource的区别
  • @cacheable 是否缓存成功_Spring Cache缓存注解
  • [1] 平面(Plane)图形的生成算法
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [AIGC 大数据基础]hive浅谈
  • [BROADCASTING]tensor的扩散机制
  • [BZOJ2281][SDOI2011]黑白棋(K-Nim博弈)