开发者学堂课程【大数据Impala教程:SQL 语法--表特定语句--分组、排序、过滤】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/722/detail/12895
SQL 语法--表特定语句--分组、排序、过滤
内容介绍:
一、order by 子句
二、group by 分组语句
三、查询结果返回控制的条数 limit ,offset
四、distinct
Impala SQL 语法当中跟表查询相关的几个特定语句。这些语法主要用于在进行数据查询分析的时候来使用。
一、order by 子句
根据指定的列控制反馈的结果排序,它可以控制所谓的升序降序,也可以控制多个列。默认情况下,如果不指定它是按照升序对结果进行一个排序,要想控制排序的方向可以用的两个单词来选择,一个叫做 asc,一个叫做 desc,asc 就是默认的升序,desc 就是降序。
后面有两个控制,控制的情况,比如说在进行指定某个列进行排序的时候,列当中恰好有些数据是空的,记录丢失了,这时候若想看一下空值它出现在哪里,对结果有没有影响,这时候就可以使用的 nulls first 把它给置前,同样的说这些控制对结果有影响,把它放到后面。nulls last,就可以控制表当中的所谓的空值出现在顶行还是在最后进行排列,接下来看一下具体的操作:
现在有一个表,往里面插了一些数据, Select * from employee,这个表当中有几个字段,id ,name age address 及salary,接下来想根据薪水看看公司的雇员的工资什么情况,在查询的时候就可以加上 order by salary。
这种情况下没有加上关键字控制排序,默认就是一个升序,这时候控制权在后面,比如双选关系,哪个工资没有统计出来,就可以 nulls first,它就出现在第一行。但是下面的依然是升序,与此同时控制它的降序,在 order by salary 后面加上 desc,大家发现空值还是位于最前面,而排序规则变成了降序,这样就控制查询的一个顺序结果。
二、group by 分组语句
这个语句通常是跟 select 做一个协作使用。分析个表,看一下相同的数据来到一组都有哪些情况,例如一个班有一个用户叫做 t-user 这么一个表,想看一下男女各有多少人,就 group by 然后在里面进行一个分组统计就可以了。
其实说到 group by 子句还要提到它分组之后的一个过滤叫做 having,进行分组,分组完之后还有结果显示,但是想控制显示的条件,不需要把所有结果都写出来,当中不符合规则的,不显示,就可以 having 再加一层过滤
具体操作如下:
比如说以上为例,想去看一下相同工资的有多少人,这时候就可以直接 select * from employee,注意后面加上分组就是 group by salary,分完组之后在每一个组内想做一统计,统计他们之间有多少个人拿到同样工资的,同时还想看一下能拿到工资的人有多少个,是什么级别的公司,把 salary 字段加进去,这样就非常清晰了,在公司当中拿到2万的有一个人,拿到1万5的一个人,拿到5万的有两个人,这样结果就比较明晰了,但是在这个结果当中也进行分组了,根据 salary 也进行统计了,若想让空值给排除掉,不想显示在最终的结果上,需要在分组之后再加一个过滤,指定哪些结果显示出来,这时候使用 having 就可以。
这也是通常所说的 having 叫做分组后过滤,这时候再把空值给它过滤掉,只要增加一个 aving salary is not null 就可以了,然后发现控制就完成了过滤,这样配合使用根据需求和相关的规则,就可以灵活的运用语法进行分析。
当中要特别强调出现在表达式中的字段要么是分组字段,要么是具有函数应用的字段,否则会报错,比如说在筛选当中再来一个 ID, ID 不是分组的,一回车直接就报错。这种表达式不支持的聚合输出。
三、查询结果返回控制的条数 limit ,offset
参与结果之后想只返回几条,再去 select from 这个表的时候,比如现在不加任何的一些查询,返回来试测表全部数据,但是只需要前两条,那这时候直接加个 limit 回车,就把前两条拿出来了,但是要注意返回前两条的同时,limit 控制反馈的结果跟全部要查询的结果不一样。
全表查询反馈的是4627513:
但是如果加一个 limit2,返回的是14,并不是46:
这里看起来是一份表的数据,实际上底层它是多个文件,比如回到 hdr 当中做一个查看,打开表,这个表它底层并不是位于一个文件当中,而是每条记录都是一个文件,它在读的时候就是并行图,在读下面这些文件都是这个表的数据的时候,只返回两条,这里又没有相关的排序规则,所以说会造成在这种情况下反馈结果不一致,想控制精准的,最好是配合其他语法来使用,比如加一个 order by salary。
当根据工资进行排序的时候,不管怎么查询几个文件,它一定是按照1万5~5万这种顺序排序的,那再加上 limit 就可以显示结果了。要知道底层有个小细节,就是隐瞒了底层数据,一个表它可能是位于多个不同的文件当中,如果说是一个文件可能就不会有这个问题了,要注意这里不要纠结为什么查询两条的时候结果不一样,事实上去查询全表的时候,过一会儿查询你发现它不一定是2173468了,可能是其他数据,反正它都是把这个表的结果显示出来。
后面这一个叫做 offset 子句,因为在默认的情况下,进行 limit 是从第一条开始的, 就是偏移量为零,比如还是要返回两条,但是想从第一条开始,在查询的时候加上一个 offset 控制它的偏移量。把控制返回条数的起始量做了一个偏移,这就是的一个查询结果控制的条数的行为 limit 加上 offset。
With 子句,这一个查询主要是涉及到查询太复杂的时候,可以先为每
个查询做一个局部定一个别名,然后再把它聚合在一块,直接通过例子就可以看出来了:
比如有两个表,一个叫做雇员表,一个叫顾客表。需求是这样的,要显示年龄大于25的员工,包括顾客也是一样,就是把这两个表当中大于25的记录都找出来,首先 with t1,t1这个结果是 select*from 这个表,这个顾客当中年龄大于25的结果采集出来,底下起个别名叫做t1,再去查询的雇员表大于25岁的,给它取名叫 t2,相当于先做了两个子查询,并且把它们命名结果,一个叫 t1,一个叫 t2。再针对 t1,t2做一个联合查询,with 子句主要是用在复杂水平当中,先进行一些局部的子查询,再把结果聚合进行后面的查询,规则掌握清楚就可以了。
三、distinct
用于结果的去除,比如现在 select*from employee,这时候想看一下这当中的一个结果, address,查询一下公司的员工到底都是来自于哪个地址的:
它会把这个表当中的所有记录,但是当中发现有些记录明显是重复的,加一个 distinct,这时候反馈就是一个去重的使用了。