目录
0. 相关文章链接
1. hive中多表full join主键重复问题
2. Hive中选出最新一个分区中新增和变化的数据
3. Hive中使用sort_array函数解决collet_list列表排序混乱问题
4. SQL中对小数位数很多的数值转换成文本的时候不使用科学计数法
5. HiveSQL & SparkSQL中炸裂函数的使用(列转行)
6. HiveSQL & SparkSQL中对时间的转换
开发随笔文章汇总
hive中多表full join主键重复问题
Hive中选出最新一个分区中新增和变化的数据
Hive中使用sort_array函数解决collet_list列表排序混乱问题
我们在SQL中,会碰到使用collect_list和concat_ws将该列的数值统计成一个字段的情况,这时候我们会发现当小数位数太多的时候,有些转换成文本的时候,就会使用科学计数了。如下SQL和图片所示:
select
concat_ws('_', collect_list(num))
from (
SELECT cast(0.000001 as double) as num
union all
SELECT cast(0.000009 as double) as num
)
;
这时如果在应用上需要这个数值进行统计的话,会发现数据错误,所以我们此时,就需要使用特定的方法,将统计出来的文本数据也展示成正常的数据显示(这样在应用上进行切分并获取对应的数据时就能获取到正确的数据);获取方式如下SQL和图片所示:
select
concat_ws('_', collect_list(cast(num as DECIMAL(20, 6))))
from (
SELECT cast(0.000001 as double) as num
union all
SELECT cast(0.000009 as double) as num
)
;
核心点:使用cast和decimal保存对应的固有位数,但是要注意decimal中当位数不足时会在后面补0,所以需要注意数值需要的保留位数和固有位数。
原始数据如下:
select
user_id
,supply_suppress_score
,dt
FROM yishou_data.dwt_user_preference_score_180day_sp_dt
where dt = 20230714 and user_id = '25887';
炸裂的语法和展示的数据如下(会新增一列:temp_field):
SELECT
user_id
, supply_suppress_score
, dt
, temp_field
FROM yishou_data.dwt_user_preference_score_180day_sp_dt
lateral view outer explode (split(supply_suppress_score, ',')) as temp_field
where dt = 20230714 and user_id = '25887'
;
-- to_date(string timestamp) 返回日期时间字段中的日期部分
-- 返回类型:string
-- 其中的cast(xxx as TIMESTAMP)是将对应的秒值转换成TIMESTAMP的毫秒值,会乘以1000
select to_date('2023-06-26 10:03:01')
-- 输出结果:2023-06-26
select to_date(CAST(1687708800 as TIMESTAMP))
-- 输出结果:2023-06-26
-- current_date() 返回当前时间日期
-- 返回类型:date
select current_date()
-- 2023-07-24
-- 通过unix_timestamp和from_unixtime 可以获取当前的时间
select from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss')
-- 2023-07-24 16:46:08
-- current_timestamp() 返回当前时间戳
-- 返回类型:timestamp
select current_timestamp()
-- 1690170111525
-- 时间戳【秒数】
select unix_timestamp()
-- 1690188440
-- date_add(string startdate, int days) 返回开始日期startdate增加days天后的日期
-- 返回类型:string
select date_add('2023-07-24', 1)
-- 2023-07-25
select date_add('2023-07-24', -1)
-- 2023-07-23
-- date_sub (string startdate, int days) 返回开始日期startdate减少days天后的日期
-- 返回类型:string
select date_sub('2023-07-24', 1)
-- 2023-07-23
select date_sub('2023-07-24', -1)
-- 2023-07-25
-- datediff(string enddate, string startdate) 返回结束日期减去开始日期的天数
-- 返回类型:int
select datediff('2023-07-23','2023-07-21')
-- 2
select datediff('2023-07-23','2023-07-25')
-- -2
-- date_format(date/timestamp/string, string fmt) 按指定格式返回date
-- 返回类型: string
select date_format('2023-07-23 10:00:00','yyyy-MM-dd')
--2023-07-23
select date_format('2023-07-23 10:00:00','yyyyMMdd')
--20230723
select date_format('2023-07-23 10:00:00','yyyy-MM')
-- 2023-07
select date_format('2023-07-23 10:00:00','yyyy')
--2023
-- 日期转年函数:year()
-- year(string/date) 返回时间字符串的年份部分
-- 返回类型:int
select year('2023-07-23 10:00:00')
-- 2023
-- 日期转月份函数:month()
-- month(string/date) 返回时间字符串的月份
-- 返回类型:int
select month('2023-07-23 10:00:00')
--7
-- 日期转天函数:day() /dayofmonth(date)
-- day(string/date) 返回时间字符串的天
-- 返回类型:int
select day('2023-07-23 10:00:00')
--23
select day('2023-07-23')
--23
select dayofmonth('2023-07-23 10:00:00')
--23
-- 日期转小时函数:hour()
-- hour(string/date) 返回时间字符串的小时数字
-- 返回类型:int
select hour('2023-07-23 10:00:00')
--10
-- 日期转分钟函数:minute()
-- minute(string/date) 返回时间字符串的分钟数字
-- 返回类型:int
select minute('2023-07-23 10:00:00')
--0
-- 日期转秒函数:second()
-- second(string/date) 返回时间字符串的分钟数字
-- 返回类型:int
select second('2023-07-23 10:00:00')
--0
-- months_between(date1, date2) 返回date1与date2之间相差的月份,如date1>date2,则返回正,否则为负
-- 返回类型:double
select months_between('2023-07-23','2023-08-25')
-- -1.06451613
select months_between('2023-07-23','2023-06-25')
-- 0.93548387
select months_between('2023-07-23','2023-07-23')
--0
-- add_months(string start_date, int num_months) 返回当前时间下再增加num_months个月的日期
-- 返回类型:string
select add_months('2023-07-23',2)
-- 2023-09-23
select add_months('2023-07-23',-2)
-- 2023-05-23
-- weekofyear(string/date) 返回时间字符串位于一年中的第几个周内
-- 返回类型:int
select weekofyear('2023-07-23 12:00:00')
-- 29
-- last_day(string date) 返回这个月的最后一天的日期,忽略时分秒部分(HH:mm:ss)
-- 返回类型:string
select last_day(current_date())
-- 2023-07-31
select last_day('2023-07-23')
-- 2023-07-31
select last_day('2023-07-23 12:00:00')
-- 2023-07-31
-- trunc(string date, string format) 返回时间的最开始年份或月份
-- 返回类型:string
select trunc(current_date(),'YY')
-- 2023-01-01
select trunc('2023-07-23','YY')
-- 2023-01-01
select trunc(current_date(),'MM')
-- 2023-07-01
select trunc('2023-07-23','MM')
-- 2023-07-01
-- 方案一:使用trunc方法获取最开始的月份
select trunc(current_timestamp(),'MM')
-- 2023-07-01
--方案二:先使用dayofmonth获取当前时间在当月的天数,然后再使用date_sub使用当前日期减去当月天数减一
select date_sub(current_date,dayofmonth(current_date)-1)
-- 2023-07-01
-- 先使用add_months函数加/减一个月,再通过trunc获取这个月的第一天
select trunc(add_months(current_timestamp(),1),'MM')
-- 先使用add_months函数加/减一个月,再通过trunc获取这个月的第一天,作为第一个参数
-- 先使用add_months函数加/减一个月,再通过last_day获取这个月的最后一天,最后通过dayofmonth获取到这个月有多少天,作为第二个参数
-- 使用date_add函数,将上述第一个参数正常填入,第二个参数减一填入
select date_add(
trunc(add_months(current_timestamp(),1),'MM') ,
dayofmonth(last_day(add_months(current_timestamp(),1))) - 1
);
-- 2023-08-31
-- next_day(string date, string week) 返回当前时间的下一个星期X所对应的日期
-- 返回类型:string
-- 注意:通过next_day和date_sub,还可以用来求取本周几
-- 下周一
select next_day(to_date(CURRENT_TIMESTAMP),'MO')
-- 2023-07-31
select next_day(CURRENT_DATE,'MO')
-- 2023-07-31
-- from_unixtime(bigint unixtime[, string format]) 转化UNIX时间戳(从1970-01-01 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式
-- 返回类型:string
select from_unixtime(1323308143,'yyyy-MM-dd')
--2011-12-08
-- unix_timestamp(string date) 转换格式为“yyyy-MM-dd HH:mm:ss“的日期到UNIX时间戳。如果转化失败,则返回0
-- 返回类型: bigint
select unix_timestamp('2019-03-07 13:01:03')
--1551934863
-- unix_timestamp(string date, string pattern) 转换pattern格式的日期到UNIX时间戳。如果转化失败,则返回0
-- 返回类型: bigint
select unix_timestamp('2009-03-20', 'yyyy-MM-dd')
--1553011200
未完待续......
注:其他相关文章链接由此进 -> 开发随笔文章汇总