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

ops/2024/9/23 22:58:36/

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

一、需求及问题描述

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

题主最近接到一个需求:

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

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

sql">SELECT deadline FROM case_3;

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

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

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

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

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

sql">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。

详情见下面的介绍

命令格式

sql">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格式的数据

sql">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,标准化之后的数据如下图所示,符合我们的预期:

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类型

详情见下面的介绍

命令格式

sql">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

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一样,只不过它是向右补齐字符串到指定长度。


http://www.ppmy.cn/ops/107784.html

相关文章

Java 利用ASM读取变量值(Field value)问题研究

最近在学习Spring源码的过程中&#xff0c;遇到了spring-asm工程的重新打包的问题&#xff0c;于是突然就想研究一下asm这个 开源字节码操作工具。秉承我的一贯风格&#xff0c;想到啥就立马学啥。 对于开源产品&#xff0c;我的一贯风格就是通过其官方提供的源码版本管理地址(…

如何恢复回收站中已删除/清空的文件

回收站清空后如何恢复已删除的文件&#xff1f;是否可以恢复永久删除的文件&#xff1f;或者最糟糕的是&#xff0c;如果文件直接被删除怎么办&#xff1f;本文将向您展示清空回收站后恢复已删除数据的最佳方法。 回收站清空后如何恢复已删除的文件&#xff1f; “回收站清空后…

git 常用命令整理

全局配置 git config --global user.name "Your Name Comes Here" # 配置使用git仓库的人员姓名 git config --global user.email youyourdomain.example.com # 配置使用git仓库的人员email git config --global credential.helper cache # 配置到缓存 默认15分…

【网络安全】DNS重绑定原理详析

原创文章,不得转载。 文章目录 DNSDNS查询过程同源策略DNS重绑定攻击原理DNS重绑定攻击步骤DNS重绑定工具工具一工具二DNS 在网络中,访问网站实际上是通过其对应的 IP 地址实现的,然而,IP 地址往往难以记忆。因此,DNS(域名系统)应运而生。 DNS(Domain Name System)是…

大数据时代的技术hive:hive的数据类型和数据模型

在上篇文章里&#xff0c;我列举了一个简单的hive操作实例&#xff0c;创建了一张表test&#xff0c;并且向这张表加载了数据&#xff0c;这些操作和关系数据库操作类似&#xff0c;我们常把hive和关系数据库进行比较&#xff0c;也正是因为hive很多知识点和关系数据库类似。 关…

Node.js的express模块

一、express介绍 express 是一个基于 Node.js 平台的极简、灵活的 WEB 应用开发框架 官方网址&#xff1a;https://www.expressjs. com.cn/ 简单来说&#xff0c;express 是一个封装好的工具包&#xff0c;封装了很多功能&#xff0c;便于我们开发 WEB 应用&#xff08;HTTP …

[论文笔记]QLoRA: Efficient Finetuning of Quantized LLMs

引言 今天带来LoRA的量化版论文笔记——QLoRA: Efficient Finetuning of Quantized LLMs 为了简单&#xff0c;下文中以翻译的口吻记录&#xff0c;比如替换"作者"为"我们"。 我们提出了QLoRA&#xff0c;一种高效的微调方法&#xff0c;它在减少内存使用…

Qt使用小技巧之按钮动态变化

前言 最近写小demo中无意发现的&#xff0c;是想实现当鼠标悬停到按钮上面的时候&#xff0c;按钮实现动态变化&#xff0c;让人知道鼠标经过了按钮&#xff0c;效果如下 hoverDynamicPushButton 正文 首先是将按钮的边框给去掉&#xff0c;然后设置下它的悬停伪状态就行了 格…