HiveSQL 工作实战总结
记录一些工作中有意思的统计指标,做过一些简化方便大家阅读,记录如有错误,欢迎在评论区提问讨论~
问题类型
- 连续问题
- 两种思路
- 第一种:日期减去一列数字得出日期相同,主要是通过
row_number
窗口函数 - 第二种:后一个日期减去前一个日期差值相等,用的较少,可以用
lag/lead
窗口函数解决
- 分组问题
- 主要使用
lag(col,1,0)
分组将每行移到下一行,再按既定规则分组排序即可 - 后面抽空试一下
- 主要使用
- 间隔连续问题,比如每断一天也算连续
- 两种思路:
- 第一种:连续使用两次连续问题的求法即可,差了几次可以连续
row_number
几次,这种无限套娃不推荐使用 - 第二种:连续差值小于要求数即可,比如断一天也可,只要每行间隔小于2天即可
- 打折日期交叉问题,两段活动期重复日期去除
- 同时在线问题
一、统计每个设备的累计告警次数
原始数据格式
deviceId | alarmDate | alarmCount |
---|---|---|
设备ID | 告警日期 | 告警次数 |
u01 | 2022/1/8 | 5 |
u02 | 2022/1/8 | 7 |
u03 | 2022/1/8 | 3 |
u01 | 2022/1/12 | 2 |
u02 | 2022/1/12 | 1 |
u01 | 2022/1/14 | 9 |
... | ... | ... |
统计之后格式
设备ID | 告警月份 | 告警次数小计 | 告警次数累计 |
---|---|---|---|
u01 | 2022-02 | 11 | 11 |
u02 | 2022-03 | 12 | 23 |
... | ... | ... | ... |
工作思路
- 先根据设备ID和告警日期分组
- 按月份统计可以用substr函数或者日期格式化函数
- 再统计即可得出小计告警次数
- 接着使用聚合窗口函数计算累计告警次数
工作语句
- 第一种方案,使用
substr
截取字符串函数
SELECT *,
SUM(sumPart) OVER (PARTITION BY deviceId ORDER BY alarmMonth) AS sumAll
FROM
(SELECT deviceId,
SUBSTR(alarmDate,1,7) AS alarmMonth,
SUM(alarmCount) AS sumPart
FROM test_00
GROUP BY deviceId,
alarmMonth) t;
- 第二种方案,使用日期格式化函数,使用
date_format
函数的字符串必须满足yyyy-MM-dd格式,所以必须先用regexp_replace
替换/
为-
SELECT *,
SUM(sumPart) OVER (PARTITION BY deviceId ORDER BY alarmMonth) AS sumAll
FROM
(SELECT deviceId,
DATE_FORMAT(REGEXP_REPLACE(alarmDate,'/','-'), 'yyyy-MM') AS alarmMonth,
SUM(alarmCount) AS sumPart
FROM test_00
GROUP BY deviceId,
alarmMonth) t;
开窗函数中的界限说明
- unbounded:无界限
- preceding:从分区第一行头开始,则为
unbounded
N为:相对当前行向后的偏移量 - following :与
preceding
相反,到该分区结束,则为unbounded
N为:相对当前行向后的偏移量 - current row:顾名思义,当前行,偏移量为0
二、统计环境设备每天的总污染告警次数,并输出每个设备告警次数排名前三的日期
原始数据格式
deviceId | alarmTime |
---|---|
设备ID | 告警时间 |
u01 | 2022/1/8/08/04/58 |
u02 | 2022/1/8/12/05/38 |
u03 | 2022/1/8/17/01/12 |
u01 | 2022/1/12/12/04/53 |
u02 | 2022/1/12/13/45/34 |
u01 | 2022/1/14/02/12/51 |
... | ... |
统计之后格式
设备ID | 告警次数累计 |
---|---|
u01 | 3 |
u02 | 2 |
u03 | 1 |
... | ... |
工作思路
统计环境设备的总污染告警次数
- 由于有设备可能会有同一时间的告警记录,所以需要按告警时间去重后再统计
- 如果使用distinct去重,如果表数据过大,且设备ID差异化很大,那么会有性能压力
- 所以使用group by子查询代替
- mysql中的
date_format
格式化需要这样写:DATE_FORMAT(alarmTime, '%Y-%c-%d %T')
输出每个设备告警次数排名前三的日期
- 使用窗口函数
ROW_NUMBER() OVER()
进行分组排序即可,MySQL 替换 ROW_NUMBER() OVER (PARTITION ……) 函数 - 多个子句查询可以使用视图和
WITH
语句
工作语句
统计环境设备的总污染告警次数
SELECT deviceId,
COUNT(alarmTime) AS alarmCount
FROM
--- http://c.biancheng.net/mysql/date_format.html
(SELECT deviceId,
DATE_FORMAT(REGEXP_REPLACE(alarmTime,'/','-'), 'yyyy-MM-dd HH:mm:ss') AS alarmTime
FROM test_01
GROUP BY deviceId,alarmTime
ORDER BY alarmTime) t
GROUP BY deviceId;
输出每个设备告警次数排名前三的日期
SELECT *
FROM
(SELECT deviceId,
alarmDate,
alarmCount,
ROW_NUMBER() OVER(PARTITION BY deviceId ORDER BY alarmCount DESC) AS alarmRank
FROM
(SELECT deviceId,
alarmDate,
COUNT(alarmDate) AS alarmCount
FROM
(SELECT deviceId,
DATE_FORMAT(alarmTime, 'yyyy-MM-dd') AS alarmDate,
DATE_FORMAT(alarmTime, 'yyyy-MM-dd HH:mm:ss') AS alarmTime
FROM test_01
GROUP BY deviceId,alarmTime
ORDER BY deviceId,alarmTime) t1
GROUP BY deviceId,alarmDate) t2) t3
WHERE alarmRank<=3;
-- 使用WITH语句优化一下
WITH t1 AS (
SELECT deviceId,
DATE_FORMAT(alarmTime, 'yyyy-MM-dd') AS alarmDate,
DATE_FORMAT(alarmTime, 'yyyy-MM-dd HH:mm:ss') AS alarmTime
FROM test_01
GROUP BY deviceId,alarmTime
ORDER BY deviceId,alarmTime),
t2 AS (
SELECT deviceId,
alarmDate,
COUNT(alarmDate) AS alarmCount
FROM t1
GROUP BY deviceId,alarmDate),
t3 AS (
SELECT deviceId,
alarmDate,
alarmCount,
ROW_NUMBER() OVER(PARTITION BY deviceId ORDER BY alarmCount DESC) AS alarmRank
FROM t2)
SELECT * FROM t3 WHERE alarmRank<=3;
COUNT(1)和COUNT(*)的区别
- 从执行结果来说
COUNT(1)
和COUNT(*)
之间没有区别,因为COUNT(*)
和COUNT(1)
都不会去过滤空值- 但
COUNT(列名)
就有区别了,因为COUNT(列名)
会去过滤空值
- 从执行效率来说
- 他们之间根据不同情况会有些许区别,MySQL会对
COUNT(*)
做优化 - 如果列为主键,
COUNT(列名)
效率优于COUNT(1)
- 如果列不为主键,
COUNT(1)
效率优于COUNT(列名)
- 如果表中存在主键,
COUNT(主键列名)
效率最优 - 如果表中只有一列,则
COUNT(*)
效率最优 - 如果表有多列,且不存在主键,则
COUNT(1)
效率优于COUNT(*)
- 他们之间根据不同情况会有些许区别,MySQL会对
三、统计每个月的总告警次数,总告警设备数,以及能够连续七天数值正常设备数量
留给你思考
四、统计出2022年1月首次出现告警的设备数量
原始数据格式
deviceId | alarmTime |
---|---|
设备ID | 告警时间 |
u01 | 2022/1/8/08/04/58 |
u02 | 2022/2/8/12/05/38 |
u03 | 2021/9/8/17/01/12 |
u01 | 2022/1/12/12/04/53 |
u02 | 2022/4/12/13/45/34 |
u01 | 2022/5/14/02/12/51 |
... | ... |
统计之后格式
设备ID | 首次告警时间 |
---|---|
xxx | 2022/1/8/08/04/58 |
xxx | 2022/1/8/12/05/38 |
xxx | 2022/1/8/17/01/12 |
... | ... |
工作思路
- 先用
date_format
格式化所有设备告警时间为yyyy-MM
的日期格式 - 运用
min
函数得出每个设备最早告警日期 - 当最早告警日期是
2022年1月
的时候即为我们所需要知道的设备记录
工作语句
WITH t1 AS (
SELECT *,
DATE_FORMAT(alarmTime, 'yyyy-MM') AS alarmMonth
FROM test_01
),
t2 AS (
SELECT deviceId,
alarmTime,
MIN(alarmMonth) AS firstAlarmMonth
FROM t1
GROUP BY deviceId
)
SELECT * FROM t2 WHERE firstAlarmMonth='2022-1';
五、根据设备地区编号段对告警次数进行排序
有一个5000万的设备信息表,一个2亿记录的告警记录表
原始数据格式
- 设备信息表
deviceId | deviceName | deviceDistrict |
---|---|---|
设备ID | 设备名称 | 设备所属地区 |
u01 | xx01 | 210000 |
u02 | xx02 | 210010 |
u03 | xx03 | 210025 |
... | ... | ... |
- 告警记录表
deviceId | alarmTime |
---|---|
设备ID | 告警时间 |
u01 | 2022/1/8/08/04/58 |
u02 | 2022/2/8/12/05/38 |
u03 | 2021/9/8/17/01/12 |
u01 | 2022/1/12/12/04/53 |
u02 | 2022/4/12/13/45/34 |
u01 | 2022/5/14/02/12/51 |
... | ... |
统计之后格式
设备地区号段 | 告警次数 |
---|---|
210000-210010 | 2 |
210010-210020 | 8 |
210020-210030 | 4 |
210040-210050 | 7 |
... | ... |
工作思路
- 先根据设备ID分组
count
统计报警次数 - 再使用casewhen条件语句,或者使用
concat/floor/ceil
函数动态划分,根据分段统计不同设备位于什么地区号段 - 最后连接查询,并根据地区号段,使用
sum
函数统计总告警次数即可
工作语句
-- 第一种方案
WITH t1 AS(
SELECT deviceId,
COUNT(alarmTime) AS alarmCount
FROM test_01
GROUP BY deviceId
),
t2 AS(
SELECT deviceId,
deviceDistrict,
-- 如果地区编号是字符串可以先转换再比较,不然会触发隐式转换,导致全表扫描无法使用索引
-- CONVERT(deviceDistrict, UNSIGNED)>=210000
CASE WHEN deviceDistrict>=210000 AND deviceDistrict<210010 THEN '210000-210010'
WHEN deviceDistrict>=210010 AND deviceDistrict<210020 THEN '210010-210020'
WHEN deviceDistrict>=210020 AND deviceDistrict<210030 THEN '210020-210030'
WHEN deviceDistrict>=210030 AND deviceDistrict<210040 THEN '210030-210040'
WHEN deviceDistrict>=210040 AND deviceDistrict<210050 THEN '210040-210050'
WHEN deviceDistrict>=210050 AND deviceDistrict<210060 THEN '210050-210060'
WHEN deviceDistrict>=210060 AND deviceDistrict<210070 THEN '210060-210070'
END deviceDistrictSection
FROM test_02
),
t3 AS (
SELECT t2.deviceDistrictSection AS deviceDistrictSection,
SUM(t1.alarmCount) AS alarmCount
FROM t1 LEFT JOIN t2
ON t1.deviceId = t2.deviceId
GROUP BY deviceDistrictSection
ORDER BY deviceDistrictSection
)
SELECT * FROM t3;
-- 第二种方案
WITH t1 AS(
SELECT deviceId,
COUNT(alarmTime) AS alarmCount
FROM test_01
GROUP BY deviceId
),
t2 AS(
SELECT deviceId,
deviceDistrict,
CONCAT(FLOOR(deviceDistrict/10)*10, '-', (FLOOR(deviceDistrict/10)+1)*10) AS deviceDistrictSection
FROM test_02
),
t3 AS (
SELECT t2.deviceDistrictSection AS deviceDistrictSection,
SUM(t1.alarmCount) AS alarmCount
FROM t1 LEFT JOIN t2
ON t1.deviceId = t2.deviceId
GROUP BY deviceDistrictSection
ORDER BY deviceDistrictSection
)
SELECT * FROM t3;
-- 第二种方案的函数测试
SELECT FLOOR(210015/10)*10 AS x; -- 210015
SELECT CEIL(210015/10)*10 AS y; -- 210020
SELECT CONCAT(FLOOR(210015/10)*10, '-', CEIL(210015/10)*10); -- 210010-210020
SELECT CONCAT(FLOOR(210020/10)*10, '-', CEIL(210020/10)*10); -- 210020-210020
SELECT CONCAT(FLOOR(210020/10)*10, '-', (FLOOR(210020/10)+1)*10); -- 210020-210030
拼接函数concat
/concat_ws
/group_concat
的区别说明
concat
- 将多个字符串连接成一个字符串
concat(str1, str2,...)
- 返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null
concat_ws
- 和concat()一样,将多个字符串连接成一个字符串,但是可以一次性指定分隔符
- 第一个参数指定分隔符,
concat_ws(separator, str1, str2, ...)
- 返回结果为连接参数产生的字符串。需要注意的是分隔符不能为null,如果为null,则返回结果为null
group_concat
- 将
group by
产生的同一个分组中的值连接起来,返回一个字符串结果 group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] )
- 说明:通过使用
distinct
可以排除重复值;如果希望对结果中的值进行排序,可以使用order by
子句;separator
是一个字符串值,缺省为一个逗号
- 将
拼接函数floor
/ceil
/round
的区别说明
floor
- 在英文中,是地面,地板的意思,有下面的意思;所以此函数是向下取整,它返回的是小于或等于函数参数,并且与之最接近的整数
- 向下取整的时候,正数,则取其整数部位,抹除小数部位
- 负数,则取其整数加一
- 整数,则不变
ceil
- 在英文中,是天花板的意思,有向上的意思;所以此函数是向上取整,它返回的是大于或等于函数参数,并且与之最接近的整数
- 向上取整的时候,正数,则直接将当前整数加一
- 负数,则将整数后面的数据抹除
- 整数,则不变
round
- 在英文中是有大约,环绕,在某某四周,附近的意思,所以,可以取其大约的意思,在函数中是四舍五入
- 四舍五入的时候,正数,小数位大于5,则整数位加一,小数位小于5,则整数位不变,抹除小数位
- 负数,小数位小于5,则整数位不变,抹除小数位,小数位大于5,则整数位加一
- 整数,则不变
MySQL中保留两位小数
round(x,d)
四舍五入保留小数round(x)
其实就是round(x,0)
,也就是默认d为0,默认不保留小数,d为保留几位小数- d可以是负数,这时是指定小数点左边的d位整数位为0,同时小数位均为0,例如:
round(114.6, -1) -> 110
truncate(x,d)
函数返回被舍去至小数点后d位的数字x,和round
函数类似,但是没有四舍五入format(x,d)
强制保留d位小数,整数部分超过三位的时候以逗号分割,并且返回的结果是string
类型的convert(value,type)
类型转换,相当于截取,例如:- convert(100.3465, decimal(10,2)) -> 100.35
- convert(100, decimal(10,2)) -> 100
- convert(100.4, decimal(10,2)) -> 100.4
Hive中保留两位小数
round(column_name,2)
四舍五入截取 这种方法慎用,有时候结果不是你想要的regexp_extract(column_name,'([0-9]*.[0-9][0-9])',1)
正则匹配截取,不做四舍五入,只是单纯的当作字符串截取cast(column_name as decimal(10,2))
cast函数截取 推荐使用
六、统计所有告警设备和所有活跃告警设备(连续三天都有告警的设备)的总数,以及平均监测值
活跃告警设备是指连续三天都有告警的设备
连续N天登录等类似题目的解题思路
- 日期减去一列数字得到的日期相等
- 后一个日期减去前一个日期的差值相等
原始数据格式
deviceId | alarmDate | alarmValueAvgDaily |
---|---|---|
设备ID | 告警日期 | 当日平均监测值 |
u01 | 2022-1-8 | 27 |
u02 | 2022-4-5 | 12 |
u03 | 2022-3-2 | 45 |
u01 | 2022-2-10 | 66 |
u02 | 2022-1-18 | 98 |
u01 | 2022-1-28 | 53 |
... | ... |
统计之后格式
类型 | 总数 | 总均值 |
---|---|---|
所有告警设备 | 18398 | 34 |
活跃告警设备 | 3213 | 87 |
工作思路
- 首先使用
group by
去除重复日期的重复数据,用max
函数取最大值 - 然后使用
group by
去除重复设备数,分别查询设备总数和总平均值,再用左连接将查询结果拼接,保存结果查询 - 接着处理统计活跃告警设备,先用
row_number
函数查询分组编号,再使用date_sub
函数用告警日期减去分组编号,得出一组临时告警日期用于判定是否是活跃告警设备 - 如果有连续相同日期说明是活跃告警设备,所以接着使用
count
函数和having
条件统计过滤有大于等于三天的连续相同日期的设备与告警日期,注意同时要计算均值 - 左后统计活跃告警设备总数和平均值,并和第二步中的结果
union all
即可
工作语句
WITH
-- 首先去除重复日期的重复数据,这里取最大值
t1 AS(
SELECT deviceId,
alarmDate,
MAX(alarmValueAvgDaily) AS alarmValueAvgDaily
FROM test_03
GROUP BY deviceId, alarmDate
),
-- 去除重复设备数
t2 AS(
SELECT *
FROM t1
GROUP BY deviceId
),
-- 查询设备总数
t3 AS(
SELECT '告警设备总数与均值' AS type,
COUNT(deviceId) AS allDeviceCount
FROM t2
),
-- 查询总均值
t4 AS(
SELECT ROUND(AVG(alarmValueAvgDaily)) AS alarmValueAvgAll
FROM t1
),
-- 查询分组后的排序编号
t5 AS(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY deviceId ORDER BY alarmDate) AS alarmDateRank
FROM t1
),
-- 查询告警日期减去分组后排序编号之后的日期,如果有连续相同的说明是连续的天数
t6 AS(
SELECT *,
DATE_SUB(alarmDate, INTERVAL alarmDateRank DAY) AS alarmDateSub
FROM t5
),
-- 查询连续天数大于3天的设备,以及这些活跃设备的平均值
t7 AS(
SELECT deviceId,
ROUND(AVG(alarmValueAvgDaily)) AS alarmValueAvgActive,
alarmDateSub,
COUNT(*) AS alarmDateSubCount
FROM t6
GROUP BY deviceId, alarmDateSub
HAVING alarmDateSubCount>=3
),
t8 AS(
SELECT '活跃告警设备总数与均值' AS type,
COUNT(deviceId) AS allDeviceCount,
ROUND(AVG(alarmValueAvgActive)) AS alarmValueAvgActiveAll
FROM t7
)
-- 统计完成所有告警设备以及平均监测值
SELECT * FROM t3 LEFT JOIN t4 ON t4.alarmValueAvgAll IS NOT NULL
UNION ALL
-- 统计完成活跃告警设备以及平均监测值
SELECT * FROM t8;
合并操作符union
和union all
之间的区别
- 相同之处
- 都是用于合并两个或多个
select
语句的结果组合成单个结果集 - 操作符内部的每个
select
语句必须拥有相同数量的,列也必须拥有相似的数据类型,同时每个select
语句中的列的顺序必须相同
- 都是用于合并两个或多个
- 不同之处
- 对重复结果的处理:
union
在进行表连接后会筛选掉重复的记录,union all
不会去除重复记录 - 对排序的处理:
union
将会按照字段的顺序进行排序,union all
只是简单的将两个结果合并后就返回 - 从效率上说,
union all
要比union
快很多,所以,如果可以确认合并的两个结果集中不包含重复数据且不需要排序时的话,那么就使用union all
- 对重复结果的处理:
Hive和MySQL中的日期函数
- MySQL Date 函数、MySQL 日期函数
- 【hive 日期函数】Hive常用日期函数整理
- 后期切记整理链接资料,若忘记请读者提醒!!!感谢!!!
七、统计2022年1月8日下午16点-17点,每个接口调用量top10的ip地址
原始数据格式
time | interface | ip |
---|---|---|
时间 | 接口 | 访问IP |
2021/1/8 15:01:28 | /api/user/login | 110.25.3.56 |
2021/1/8 15:21:12 | /api/device/alarm | 23.21.33.87 |
2021/1/8 15:51:34 | /api/device/record | 45.76.21.543 |
... | ... |
统计之后格式
接口 | 访问IP | 访问次数 | 排名 |
---|---|---|---|
/api/user/login | 110.25.3.56 | 89 | 1 |
/api/device/alarm | 23.21.33.87 | 123 | 1 |
/api/device/record | 45.76.21.543 | 23 | 1 |
... | ... | ... | ... |
此题作为开放题供大家查阅,后面有空再继续写
附录资料
Hive和MySQL中部分函数的区别
- date_format()
- Hive
date_format(date date / timestamp time / string 'xxxx-xx-xx', format 'yyyy-MM-dd')
,只能识别用-
连接的日期字符串 - MySQL
date_format(date, format)
,具体的format规则请查询参考资料
- Hive
- date_sub()
- Hive
date_sub(date date / timestamp time, int days)
- MySQL
date_sub(date, interval 时间间隔 type)
,具体的type规则请查询参考资料
- Hive
Hive和MySQL常用日期函数
date_add()
向日期添加指定的时间间隔date_sub()
从日期减去指定的时间间隔datediff()
返回两个日期之间的天数
Hive中order by
/distribute by
/sort by
/group by
/partition by
之间的区别说明
- order by
order by
会对数据进行全局排序,和oracle、mysql等数据库中的order by
效果一样- 需要注意的是,hive执行过程中它只在一个
reduce
中进行,所以数据量特别大的时候效率非常低 group by
分组之后是会组内聚合的,而distribute by
和partition by
仅仅是分组了,并未有聚合操作
- distribute by
distribute by
是控制在map
端如何拆分数据给reduce
端的- hive会根据
distribute by
后面列,对应reduce
的个数进行分发,默认是采用hash算法
- sort by
sort by
为每个reduce
产生一个排序文件- 在有些情况下,你需要控制某个特定行应该到哪个
reducer
,这通常是为了进行后续的聚集操作distribute by
刚好可以做这件事 - 因此,
distribute by
经常和sort by
配合使用
- group by
- 和
distribute by
类似 都是按key值
划分数据 都使用reduce
操作 - 唯一不同的是,
distribute by
只是单纯的分散数据,distribute by col
是按照col列
把数据分散到不同的reduce
- 而
group by
把相同key值
的数据聚集到一起,后续必须是聚合操作
- 和
- cluster by
- 按列分桶建表使用
distribute by
和sort by
合用就相当于cluster by
,但是cluster by
不能指定排序为asc(升序)
或desc(倒序)
的规则,只能是升序排列
- partition by
- 按所分区名分区建表使用
- 通常查询时会对整个数据库查询,而这带来了大量的开销,因此引入了
partition
的概念 - 在建表的时候通过设置
partition
的字段,会根据该字段对数据分区存放,更具体的说是存放在不同的文件夹 - 这样通过指定设置
partition
的字段条件查询时可以减少大量的开销 - 区内排序用
order by
MySQL多表查询时如何将NULL
置为0
使用IFNULL("字段", 0)
函数即可
Hive中如何处理NULL值和空字符串
- Hive表中默认将
NULL
存为\N
,可查看表的源文件(hadoop fs -cat
或者hadoop fs -text
),文件中存储大量\N
,这样造成浪费大量空间 - 但Hive的
NULL
有时候是必须的- Hive中
insert
语句必须列数匹配,不支持不写入,没有值的列必须使用NULL
占位 - Hive表的数据文件中按分隔符区分各个列,空列会保存
NULL(\n)
来保留列位置,
但外部表加载某些数据时如果列不够,如表13列,文件数据只有2列,则在表查询时表中的末尾剩余列无数据对应,自动显示为NULL
- Hive中
- 所以,NULL转化为空字符串,可以节省磁盘空间
- 建表时直接指定
# 第一种方式
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES ('serialization.null.format' = '')
# 第二种方式
ROW FORMAT DELIMITED NULL DEFINED AS ''
- 修改已存在的表
ALTER TABLE hive_tb SET SERDEPROPERTIES('serialization.null.format' = '');
- 使用函数处理NULL值
NVL(expr1,expr2)
如果第一个参数为NULL
那么显示第二个参数的值,如果第一个参数的值不为NULL
,则显示第一个参数本来的值Coalesce(expr1, expr2, expr3….. exprn)
返回表达式中第一个非空表达式,如果所有自变量均为NULL
,则 COALESCE 返回NULL
SELECT COALESCE(NULL,null,3,4,5); -- 结果为:3
SELECT COALESCE(NULL,null,'',3,4,5); -- 结果为:''
SELECT COALESCE(NULL,null,null,NULL); -- 结果为:null
我是 fx67ll.com,如果您发现本文有什么错误,欢迎在评论区讨论指正,感谢您的阅读!
如果您喜欢这篇文章,欢迎访问我的 本文github仓库地址,为我点一颗Star,Thanks~
转发请注明参考文章地址,非常感谢!!!
HiveSQL 工作实战总结的更多相关文章
- MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验
原文地址:http://liangweilinux.blog.51cto.com/8340258/1728131 首先在此感谢下我的老师年一线实战经验,我当然不能和我的老师平起平坐,得到老师三分之一的 ...
- [转]MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验
本文转自:http://liangweilinux.blog.51cto.com/8340258/1728131 年,嘿,废话不多说,下面开启MySQL优化之旅! 我们究竟应该如何对MySQL数据库进 ...
- Linux运维工程师需要掌握什么才能胜任工作呢
万丈高楼平地起,所有一切的高深的技术都离不开最基本的技术,那么作为运维工程师的你,什么是最基本的技术呢,毫无疑问是Linux,Linux 是你所有一切技术的根源,试想一下如果你连基础的操作命令都不知道 ...
- HTTP缓存协议实战
一.什么是缓存 缓存,又称作Cache,我们把临时存储数据的地方叫做缓存池,缓存池里面放的数据就叫做缓存.当用户需要使用这些数据,首先在缓存中寻找,如果找到了则直接使用.如果找不到,则再去其他数据源中 ...
- 【转载】应读者强烈要求给出《超容易的Linux系统管理入门书》一书的主要知识点
刚开始了一篇连载,收到广大Linux爱好者的反馈,非常欣慰.大家对Linux学习感到很迷茫,不知道学哪些内容,如何学习? <超容易的Linux系统管理入门书>一书是腾讯Linux专家在腾讯 ...
- 我的微软.net演进路线图
原文地址:我的微软.net演进路线图 我的微软.net演进路线图 我的这几年,编程方面主要是跟在微软旗下奔跑的,主要语言是C# 集成开发环境(IDE) .NET Framework版本 介入年份 Vi ...
- mysql索引使用技巧及注意事项
一.索引的作用 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 在数据 ...
- C++学习建议
C++学习建议 C++缺点之一,是相对许多语言复杂,而且难学难精.许多人说学习C语言只需一本K&R<C程序设计语言>即可,但C++书籍却是多不胜数.我是从C进入C++,皆是靠阅读自 ...
- putty加了密钥ssh不能登陆,PuTTY:server refused our key问题的解决(转)
直接上方法:禁用系统的selinux功能,命令#setenforce0,但重启系统,selinux仍然启用.根治方法:更改SElinux的配置文件/etc/selinux/config,修改SELIN ...
- 并发基础(十) 线程局部副本ThreadLocal之正解
本文将介绍ThreadLocal的用法,并且指出大部分人对ThreadLocal 的误区. 先来看一下ThreadLocal的API: 1.构造方法摘要 ThreadLocal(): 创建一个线程 ...
随机推荐
- 力扣77(Java)-组合(中等)
题目: 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合. 你可以按 任何顺序 返回答案. 示例 1: 输入:n = 4, k = 2输出:[ [2,4], [3,4], ...
- 一文搞懂传统单节点网站的 Serverless 上云
简介: 阿里云函数计算 FC 是事件驱动的全托管计算服务,真正的无需去考虑服务器的运维管理,只需要完成开发的代码进行上传,函数计算会通过角色策略去规划计算资源,弹性的方式执行函数,最后高效的执行部署. ...
- 阿里云2020上云采购季,你最pick哪个产品组合?
阿里云2020上云采购季如火如荼进行中,活动还剩最后10天啦,你的云产品都买好了吗? 还没买的,还没逛的,请戳:https://www.aliyun.com/sale-season/2020/proc ...
- 急速上线 Serverless 钉钉机器人“防疫精灵”
新型冠状病毒疫情肆虐的春节,大家都过得人心惶惶,作为被关在家的程序狗,总觉得要做点什么.于是阿里云 IoT 事业部的几个同学就开始了防疫精灵的开发之路. 从点子到防疫宝,只花了一个下午时间:从防疫宝到 ...
- T级内存,创建效率提升10倍以上,阿里云 KVM异构虚拟机启动时间优化实践
简介: 阿里云工程师李伟男和郭成在 KVM Forum 2020 上详细介绍了阿里云 KVM 虚拟机创建及启动时间优化的具体技术实现,本文根据其演讲整理而成. 对于云计算用户来说,过长的 KVM 虚拟 ...
- DataV 3D 平面地图 2.0 焕新上线
简介:DataV3月,3D平面地图2.0现已上线~ 3D 平面地图 2.0 现已上线~ 让我们来看看更新了哪些功能吧! 01 交互升级,省市区自由下钻 自带行政区域数据,无需配置: 甚至,可以通 ...
- 解密万亿参数M6模型预训练背后的分布式框架Whale
简介: 最近,阿里云PAI团队和达摩院智能计算实验室一起发布"低碳版"巨模型M6,大幅降低万亿参数超大模型训练能耗.借助我们自研的Whale框架仅使用480卡GPU,即训练出了规 ...
- dotnet core 3.1 将 UWP 控件嵌入到 WPF 应用 收到 UIA 消息主线程卡住
本文记录一个问题,此问题是在 .NET Core 3.1 的 WPF 应用里面,嵌入 UWP 控件之后,在收到 UIA 的消息时,可能让主线程卡住.暂时此问题还不知道具体的复现步骤,此问题预计和 WP ...
- WPF 触摸底层 PenImc 是如何工作的
在 WPF 里面有其他软件完全比不上的超快速的触摸,这个触摸是通过 PenImc 获取的.现在 WPF 开源了,本文就带大家来阅读触摸底层的代码,阅读本文需要一点 C# 和 C++ 基础 现在 WPF ...
- 超好用的 Redis GUI 工具,你值得拥有
超好用的 Redis GUI 工具,你值得拥有 提供原生的性能,并且比使用 Electron 等 Web 技术开发的同等应用程序消耗的资源少得多. 下载地址:http://www.redisant.c ...