数据分析SQL必会语句


SQL mindmap

基本 select 语句

  1. 把数据从表中取出
--从table_1中选择a这一列
select a from table_1
  1. 双表连接查询
--table_1中有id,age; table_2中有id,sex。想取出id,age,sex 三列信息
--将table_1,table_2 根据主键id连接起来
select a.id,a.age,b.sex from (select id, age from table_1)a --将select之后的内容存为临时表a
join (select id, sex from table_2)b--将select之后的内容存为临时表b
on a.id = b.id
  1. 合并两张表
--不去重,合并两张表的数据
select * from (select id from table_1 UNION ALL select id from table_2)t;

unionunion all 均基于列合并多张表的数据,所合并的列格式必须完全一致。union的过程中会去重并降低效率,union all 直接追加数据。union 前后是两段select 语句而非结果集。

最常用

table_1

  1. 去重 distinct
-- 罗列不同的id
select distinct id from table_1
-- 统计不同的id的个数
select count(distinct id) from table_1
-- 优化版本的count distinct
select count(*) from (select distinct id from table_1) tb

distinct 会对结果集去重,对全部选择字段进行去重,并不能针对其中部分字段进行去重。使用count distinct进行去重统计会将reducer数量强制限定为1,而影响效率,因此适合改写为子查询。

  1. 聚合函数和group by
-- 统计不同性别(F、M)中,不同的id个数
select count(distinct id) from table_1 group by sex
-- 其它的聚合函数例如:max/min/avg/sum

-- 统计最大/最小/平均年龄
select max(age), min(age), avg(age) from table_1 group by id
  1. 筛选 where/having
-- 统计A公司的男女人数
select count(distinct id) from table_1 where company = 'A' group by sex

--统计各公司的男性平均年龄,并且仅保留平均年龄30岁以上的公司
select company, avg(age) from table_1 where sex = 'M' group by company having avg(age) >30;
  1. 排序 order by
-- 按年龄全局倒序排序取最年迈的10个人
select id,age from table_1 order by age DESC
limit 10
  1. 将数值型的变量转化为分类型的变量, case when 条件函数
-- 收入区间分组
select id, (case when CAST(salary as float)>50000 then '0-5万'
when CAST(salary as float) >= 50000 and CAST(salary as float)< 100000 then '5-10万'
when CAST(salary as float) >=100000 and CAST(salary as float)<200000 then '10-20万'
when CAST(salary as float)>200000 then '20万以上'
else NULL end
from table_1;

case 函数的格式为(case when 条件1 then value1 else null end), 其中else 可以省,但是end不可以省。

在这个例子里也穿插了一个CAST的用法,它常用于string/int/double型的转换。

  1. 字符串
    6.1 concat( A, B...)返回将A和B按顺序连接在一起的字符串,如:concat('foo', 'bar') 返回’foobar’
select concat('www','.baidu','.com') from iteblog;
--得到 www.baidu.com

6.2 split(str, regex)用于将string类型数据按regex提取,分隔后转换为array

--以","为分隔符分割字符串,并转化为array
select split("1,2,3",",")as value_array from table_1;
-- 结合array index,将原始字符串分割为3列
select value_array[0],value_array[1],value_array[2] from(select split("1,2,3",",")as value_array from table_1)t

6.3 substr(str,0,len) 截取字符串从0位开始的长度为len个字符。

select substr('abcde',3,2) from iteblog;
-- 得到cd

基础进阶

  1. 不想全局排序,需要分组排序—— row_number()
-- 按照字段salary倒序编号
select *, row_number() over(order by salary desc) as row_num from table_1;

-- 按照字段deptid分组后再按照salary倒序编号
select *, row_number() over(patition by depid order by salary desc) as rank from table_1;

row_number()
按照depid分组,对salary进行排序(倒序)

除了row_number函数之外,还有两个分组排序函数,分别是rank()dense_rank()

  • rank()排序相同时会重复,总数不会变 ,意思是会出现1、1、3这样的排序结果;
  • dense_rank()排序相同时会重复,总数会减少,意思是会出现1、1、2这样的排序结果。
  • row_number()则在排序相同时不重复,会根据顺序排序。
  1. 获取top10%的值—— percentile百分位函数
-- 获取income字段的top10%的阈值
select percentile (CAST (salary as int),0.9) as income_top10p from table_1;

-- 获取income字段的10个百分位点
select percentile(CAST (salary as int),0.9), array(0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0))
as income_percentiles from table_1;
  1. 对时间字段进行操作—— 时间函数
-- 转换为时间数据的格式
select to_date("1970-01-01 00:00:00") as start_time from table_1;

-- 计算数据到当前时间的天数差 
select datediff ('2016-12-30','2016-12-29'); --输出1

to_date函数可以把时间的字符串形式转化为时间类型,再进行后续的计算;

  • 常用的日期提取函数包括 year()/month()/day()/hour()/minute()/second()
  • 日期运算函数包括datediff(enddate,stratdate)计算两个时间的时间差(day)
  • date_sub(stratdate,days) 返回开始日期startdate减少days天后的日期。
  • date_add(startdate,days) 返回开始日期startdate增加days天后的日期。

常见笔试/面试题

例:有3个表S,C,SC:
S(SNO,SNAME)代表(学号,姓名)
C(CNO,CNAME,CTEACHER)代表(课号,课名,教师)
SC(SNO,CNO,SCGRADE)代表(学号,课号,成绩)

问题:

  1. 找出没选过“黎明”老师的所有学生姓名。
  2. 列出2门以上(含2门)不及格学生姓名及平均成绩。
  3. 既学过1号课程又学过2号课所有学生的姓名。
1. -- 考察条件筛选
select sname from s where sno not in
( select sno from sc where cno in  
 (
select distinct cno from c where cteacher='黎明' 
  )
);

2. -- 考察聚合函数,条件筛选
select s.sname, avg_grade from s
join
(select sno from sc where scgrade < 60 group by sno having count(*) >= 2) t1
on s.sno = t1.sno
join
(select sno, avg(scgrade) as avg_grade from sc group by sno ) t2
on s.sno = t2.sno;

3. -- 考察筛选、连接
select sname from
 ( select sno from sc where cno = 1) a
join 
 (select sno from sc where cno = 2) b
on a.sno = b.sno

来源: SQL | 数据分析面试必备SQL语句+语法

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
数据分析SQL面试必会的6道经典题目如下: 1. 查询每个部门的平均工资: 这道题考察了对于聚合函数的理解和使用,以及对于JOIN操作的熟练程度。可以使用GROUP BY语句按照部门分组,再使用AVG函数计算平均工资。 2. 查询每个部门的员工数量及平均工资: 这个问题侧重于多表之间的关联查询和聚合函数的使用。需要使用JOIN操作将部门信息表和员工信息表进行连接,并使用COUNT函数计算员工数量和AVG函数计算平均工资。 3. 查询每个部门的最高工资及对应的员工: 这个问题需要使用子查询来解决。首先根据部门分组计算每个部门的最高工资,然后再使用子查询将相应的员工信息查询出来。 4. 查询工资低于平均工资的员工: 这个问题需要使用子查询和比较操作符。首先使用子查询计算出平均工资,然后在主查询中使用比较操作符筛选出工资低于平均工资的员工。 5. 查询有重复姓名的员工信息: 这个问题需要使用GROUP BY和HAVING子句来解决。首先使用GROUP BY姓名,再使用HAVING子句筛选出有重复姓名的员工信息。 6. 查询入职日期在某个范围内的员工数量: 这个问题需要使用比较操作符和日期函数。通过比较入职日期和给定的范围日期,筛选出符合条件的员工,并使用COUNT函数计算员工数量。 以上是数据分析SQL面试中常见的6道经典问题,掌握了这些问题的解决方法,可以在面试中更好地展现自己的能力和经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值