SQL常用函数

  • hive 计算千分位数
其中percentile要求输入的字段必须是int类型的,而percentile_approx则是数值类似型的都可以 .

例如percentile_approx(grade, 0.95) 取得排位在倒数第5%的成绩。(使用时会对成绩进行排序,一般可以用于求中位数)
要求多个分位数时,可以把p换为array(),即
   percentile_approx(col,array(0.05,0.5,0.95),9999)   或者  

percentile_approx(cast(col as double),array(0.05,0.5,0.95),9999
结果为

[0.0,4001.0,4061.0]

explode(percentile_approx(cast(col as double),array(0.05,0.5,0.95),9999))as percentile 结果转换为列
eg: percentile_approx(nvl(daily_order_cnt,0), 0.95) as nf
  • nvl 函数
1.NVL函数的格式如下:NVL(expr1,expr2)
含义是:如果oracle第一个参数为空那么显示第二个参数的值,如果第一个参数的值不为  空,则显示第一个参数本来的值。

2.NVL2函数的格式如下:NVL2(expr1,expr2, expr3)
含义是:如果该函数的第一个参数为空那么显示第二个参数的值,如果第一个参数的值不为空,则显示第三个参数的值。SQL> select ename,NVL2(comm,-1,1) from emp;

3.NULLIF(exp1,expr2)函数的作用是如果exp1和exp2相等则返回空(NULL),否则返回第一个值。

4.Coalesce(expr1, expr2, expr3….. exprn)
表示可以指定多个表达式的占位符。所有表达式必须是相同类型,或者可以隐性转换为相同的类型。
返回表达式中第一个非空表达式,如有以下语句:   SELECT     COALESCE(NULL,NULL,3,4,5) FROM dual   其返回结果为:3
如果所有自变量均为 NULL,则 COALESCE 返回 NULL 值。   COALESCE(expression1,...n) 与此 CASE 函数等价:
  • MONTHS_BETWEEN函数
MONTHS_BETWEEN (x, y)用于计算x和y之间有几个月。如果x在日历中比y早,那么MONTHS_BETWEEN()就返回一个负数
SELECT MONTHS_BETWEEN('25-MAY-2008', '15-JAN-2008') FROM dual; ------------------------------------------.32258065  
  • CAST 函数
CAST函数语法规则是:Cast(字段名 as 转换的类型 ),其中类型可以为:
CHAR[(N)] 字符型
DATE 日期型
DATETIME 日期和时间型
DECIMAL float型
SIGNED int
TIME 时间型
  • UNION函数
说明:union函数是行级连接,增加行数

例如:(不包括重复的)

select * from student_drb where bno=1
union
select * from student_drb where bno=4

此结果是将select * from student_drb where bno=4查出的结果合并到
select * from student_drb where bno=1结果下面
  • UNION ALL
insert overwrite table TABLE_NAME
select X from ...
union all
select X from ...;
-- 表示:将多个查询的结果合并,表中的数据都罗列出来(包括重复的)
-- 注:"X"的位置必须相同
  • 时间戳转化
在sql查询时将日期转为时间戳
NOW():当前日期时间
SELECT UNIX_TIMESTAMP(NOW());
将日期格式转成时间戳 1493016522
SELECT UNIX_TIMESTAMP(create_time);
在sql查询时将时间戳转为日期
SELECT FROM_UNIXTIME(1493016148);
将时间戳转成日期格式 2017-04-24 14:42:28
  • TIMESTAMP
1、current_date
-- 表示:当前日期,yyyy-MM-dd
2、current_time
-- 表示:当前时间,HH:mm:ss
3、current_timestamp
-- 表示:返回当前UTC时间(GMT+0)的时间戳,小于北京时间8小时,就是日期时间yyyy-MM-dd HH:mm:ss
4、unix_timestamp()
4.1、unix_timestamp() 
    -- 得到当前时间戳. 
4.2、unix_timestamp(string date)
    -- 如果参数date满足yyyy-MM-dd HH:mm:ss形式,则可以直接 得到参数对应的时间戳.
    -- 如果参数date不满足yyyy-MM-dd HH:mm:ss形式,则我们需要指定date的形式,再进行转换 
        如:unix_timestamp(‘2009-03-20’, ‘yyyy-MM-dd’)=1237532400
5、from_unixtime(unix_timestamp,format)
-- 表示:返回表示 Unix 时间标记的一个字符串,根据format字符串格式化。 
语法:from_unixtime(t1,’yyyy-MM-dd HH:mm:ss’) 
其中t1是10位的时间戳值,即1970-1-1至今的秒,而13位的所谓毫秒的是不可以的。 
对于13位时间戳,需要截取,然后转换成bigint类型,因为from_unixtime类第一个参数只接受bigint类型。 例如: 
from_unixtime(cast(substring(tistmp,1,10) as bigint),’yyyy-MM-dd HH’)
  • IN函数
in 操作符: 
 
SELECT * FROM table1 WHERE age1 IN(11,1);

查询来自表哥table1的数据,条件为age1 在(11,1)这两个数之中,其中in的意思就是说查询的数据在什么之中。那么我们这样使用in就可以查询age1为11和1的数据了。

注意:
(1)在使用IN 和 NOT IN 时要注意 IN范围中有NULL和空值的情况
(2)尽量不要用IN和NOT IN的方式而是转换为LEFT JOIN的形式
(3)在where语句中考虑NULL的同时要考虑空字符串的情况
  • SUBSTR和SUBSTRING区别
两者都是截取字符串。

1.相同点:如果只是写一个参数,两者的作用都一样:都是是截取字符串从当前下
标以后直到   字符串最后的字符串片段
var str = '123456789';
console.log(str.substr(2));    //  "3456789"
console.log(str.substring(2)) ;//  "3456789"

2.不同点:第二个参数
substr(startIndex,lenth): 第二个参数是截取字符串的长度(从起始点截取某个长度的字符串);
substring(startIndex, endIndex): 第二个参数是截取字符串最终的下标
 (截取2个位置之间的字符串,‘含头不含尾’)。
例子1:
console.log("123456789".substr(2,5));    //  "34567"
console.log("123456789".substring(2,5)) ;//  "345"
例子2:
var a="abcdefghiklmnopqrstuvwxyz";
var b=a.substr(3,5);
var c=a.substring(3,5);
打印输出的结果是:
defgh
de
注意最后5下标是不会取到的意思是只能截取a字符串的3,4下标
截取的时候是不会截取到最后一个[3,5)
String.substr(startIndex,lenth) 这个是我们常用的从指定的位置(startIndex)截取指定长度(lenth)的字符串; 
String.substring(startIndex, endIndex) 这个是startIndex,endIndex里找出一个较小的值,
然后从字符串的开始位置算起,
截取较小值位置和较大值位置之间的字符串,截取出来的字符串的长度为较大值与较小值之间的差。
  • WITH 连接词
with TABLE_NAME AS (
SELECT ... FROM ... WHERE ...
)
-- 首个连接需要with,后续不要with:
TABLE_NAME AS (
SELECT ... FROM ... WHERE ...
  • ROW_NUMBER() over(partition by A order by B asc/desc)
row_number() over(partition by A order by B asc/desc)

-- 将查询结果按照A字段分组(partition),
-- 然后组内按照B字段排序,至于asc还是desc,可自行选择,
-- 然后为每行记录返回一个row_number用于标记顺序(编号)

特色功能:给 已有hive表(dm.official_accounts_funscount_w) 添加一列序号(sample_key),例:
select 
  row_number() over(
    partition by case when t.source is not null then 1 end
order by t.source asc,t.funCounts desc
) as sample_key,
  t.source,
  t.cityName,
  t.weight,
  t.strArea,
  t.end_date,
  t.funCounts
from dm.official_accounts_funscount_w t;
  • Row number 和RANK 和DENSE区别
RANK() 排序相同时会重复,总数不会变
DENSE_RANK() 排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算
image.png
  • CONCAT(a,b) 和concat_ws
1.concat('hello_','world')
-- 将a字符串与b字符串拼接 ==>('hello_world')
concat函数在连接字符串的时候,只要其中一个是NULL,那么将返回NULL

hive> select concat('a','b');
OK
ab
Time taken: 0.477 seconds, Fetched: 1 row(s)
hive> select concat('a','b',null);
OK
NULL
Time taken: 0.181 seconds, Fetched: 1 row(s)


2.concat_ws函数在连接字符串的时候,只要有一个字符串不是NULL,就不会返回NULL。
concat_ws函数需要指定分隔符。

hive> select concat_ws('-','a','b');
OK
a-b
Time taken: 0.245 seconds, Fetched: 1 row(s)
hive> select concat_ws('-','a','b',null);
OK
a-b
Time taken: 0.177 seconds, Fetched: 1 row(s)
hive> select concat_ws('','a','b',null);
OK
ab
Time taken: 0.184 seconds, Fetched: 1 row(s)
  • Collect_set和Collect_list函数
    image.png

    image.png
  • OVERWRITE与INTO
insert overwrite table TABLE_NAME;
-- 表示:删除原有数据然后在新增数据,如果有分区那么只会删除指定分区数据,其他分区数据不受影响。

insert into table TABLE_NAME;
-- 表示:在原有数据的基础上增加数据
  • DECIMAL
decimal(38,2)
-- 表示:计算结果保留有效位38位,小数位2位
  • IF()
if("表达式",true,null)
-- 如果表达式成立,取参数true,否则取参数null
  • COALESCE
Coalesce(expr1, expr2, expr3….. exprn)
-- 表示:返回第一个非空参数(所有参数必须是相同类型,或可隐性转换为相同的类型)。
  • LEFT REGHT INNER join
 sql的left join 、right join 、inner join之间的区别

    -left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 
    -right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
    -inner join(等值连接) 只返回两个表中联结字段相等的行
    
 左连接:
    select u.UserID,u.UserName,c.id,c.name
    from t_user u left join t_class c   on  c.id  = u.UserID
  三表关联:
select table a left join table b(left join table c on b.id = c.tb_id) on a.id = b_ta.id
  • GROUP_CONCAT
使用GROUP_CONCAT合并列,使用distinct会去掉列里面重复的数据

SELECT GROUP_CONCAT(distinct main.relator_name SEPARATOR ';') AS relator_name,
GROUP_CONCAT(distinct main.law_investigation_situ SEPARATOR ';') AS law_investigation_situ,main.relator_type,
main.asset_id
from amc.
  • GROUP BY
group by语法可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表。
SELECT子句中的列名必须为分组列或列函数。列函数对于GROUP BY子句定义的每个组各返回一个结果。

Group by 一般和聚合函数一起使用才有意义,比如 count sum avg等,使用group by的两个要素: 
 (1) 出现在select后面的字段 要么是聚合函数中的,要么是group by 中的. 
 (2) 要筛选结果 可以先使用where 再用group by 或者先用group by 再用having(having对group by进行条件帅选分组)
  • DISTINCT 去重
如何用distinct消除重复记录的同时又能选取多个字段值?

需求是:我要消除name字段值重复的记录,同时又要得到id字段的值,其中id是自增字段。 
select distinct name from t1 能消除重复记录,但只能取一个字段,现在要同时         取id,name这2个字段的值。 
select distinct id,name from t1 可以取多个字段,但只能消除这2个字段值全部相同的记录 
最后解决方法: 
SELECT id,name FROM t1 WHERE id IN(SELECT MAX(id) FROM t1 GROUP BY name) order by id desc

注意开头的 id 的 一定要,后面的order by 里有的字段一定要加进select 结果,要不然排序无效

注意:

1 .Distinct 位置 
单独的distinct只能放在开头,否则报错,语法错误 

2.与其他函数使用时候,没有位置限制如下 
Select player_id,count(distinct(task_id))from task; 
这种情况下是正确的,可以使用
  • WMSYS.WM_CONCAT()
    函数可以实现行转列的效果
    image.png
  • **hive count **
  • count(*)与count(1)
    这两种写法计算结果相同,都是计算总行数包括字段值为NULL的行
  • count(a)将返回a字段不为NULL的行数,所以为3
    select count(a>1) from t1;
    count(distinct a)去重统计也会排除字段为NULL的值。
    select count(distinct case when a>1 then a else NULL end) from t1
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359