子查询
一个 SELECT 语句的查询结果能够作为另一个语句的输入值,三种主要情况为:
1:子查询可以出现在Where子句中,作为过滤条件
- Select 列名
- From 表名
- Where 列 操作符 (Select 列名 From 表名)
2:也可以出现在from子句中,作为一个临时表使用
- Select 列名
- From (Select 列名 From 表名)
3:能够出现在select list中,作为一个字段值来返回
- Select 列名, (Select 列名 From 表名)
- From 表名
- Where 列 操作符
注意:1(当作字段的子查询)和3(当作过滤条件的子查询)的子查询只能一个字段。2(当作表的子查询可以多个字段,其中有的字段可以不用)否则语法错误。
子查询实战练习零售数据分析
一.连接远程服务器数据库(需对方提供用户名密码)
二.数据说明
2.1 在数据库中可访问的表列举如下:
2.2 主要表展示如下:
二.需求说明
1、2017年7月2号计算每个会员购买金额,以及每个会员购买金额占总体金额的比(子查询-select)
2、 2017年7月2号对每位会员累计购买金额进行分段(子查询-from)
3、 2017年7月2号统计累计购买金额在100到200的会员,寻找这批会员的消费记录(子查询-where)
注意:
- 时间型的字符,文本型字符在where 过滤如果是常量,需要 用’’
- 子查询在select 上面,一定是只能一个字段;否则语法错误。
三.(子查询-select)题目
2017年7月2号计算每个会员购买金额,以及每个会员购买金额占总体金额的比
答案一
select dimMemberID
,sum(AMT) as money
,(select sum(amt) from dw.fct_sales where dimDateID='20170702' and dimMemberID<>0) as total_money
,sum(AMT)/ (select sum(amt) from dw.fct_sales where dimDateID='20170702' and dimMemberID<>0) as member_rate
from dw.fct_sales
where dimDateID = '20170702'
and dimMemberID<>0
group by dimMemberID
order by sum(AMT) desc;
答案一结果:
答案二:(比例希望是百分比——用concat()函数)
select dimMemberID
,sum(AMT) as money
,(select sum(amt) from dw.fct_sales where dimDateID='20170702' and dimMemberID<>0) as total_money
,sum(AMT)/ (select sum(amt) from dw.fct_sales where dimDateID='20170702' and dimMemberID<>0) as member_rate
,concat(sum(AMT)/ (select sum(amt) from dw.fct_sales where dimDateID='20170702' and dimMemberID<>0)*100,'%') as member_rate_100
from dw.fct_sales
where dimDateID = '20170702'
and dimMemberID<>0
group by dimMemberID
order by sum(AMT) desc;
答案二结果:
答案:(百分比转化为两位小数——用concat(round())函数)
select dimMemberID
,sum(AMT) as money
,(select sum(amt) from dw.fct_sales where dimDateID='20170702' and dimMemberID<>0) as total_money
,sum(AMT)/ (select sum(amt) from dw.fct_sales where dimDateID='20170702' and dimMemberID<>0) as member_rate
,concat(sum(AMT)/ (select sum(amt) from dw.fct_sales where dimDateID='20170702' and dimMemberID<>0)*100,'%') as member_rate_100
,concat(round(sum(AMT)/ (select sum(amt) from dw.fct_sales where dimDateID='20170702' and dimMemberID<>0),4)*100,'%') as member_rate_100_2
from dw.fct_sales
where dimDateID = '20170702'
and dimMemberID<>0
group by dimMemberID
order by sum(AMT) desc;
答案三结果:
四.(子查询-from)题目
2017年7月2号对每位会员累计购买金额进行分段
答案:
--- 首先生成临时表
select dimMemberID
,sum(AMT) as money
from dw.fct_sales
where dimDateID = '20170702'
and dimMemberID<>0
group by dimMemberID
order by sum(AMT) desc;
--然后进行分段
select dimMemberID
,money
,case when money<100 then 'D'
when money>=100 and money<500 then 'C'
when money>=500 and money<1000 then 'B'
when money>=1000 then 'A'
end as type_money
from
(select dimMemberID
,sum(AMT) as money
,count(salesNo) as order_nubmer
from dw.fct_sales
where dimDateID = '20170702'
and dimMemberID<>0
group by dimMemberID
order by sum(AMT) desc ) as t;
答案结果:
注意:
1.子查询在from 后面,当作一个临时表来用,必须给这个子查询生成的临时表给一个表的别名!
2.当子查询是在from 后面,是可以有多个字段的,但是有的字段可以不用;因为它就是一种数据表。
五.(子查询-where)题目
2017年7月2号统计累计购买金额在100到200的会员,寻找这批会员的消费记录
答案:(用having)
--首先找到这样的会员(作为过滤条件用)
select dimMemberID
,sum(AMT) as money
from dw.fct_sales
where dimDateID = '20170702'
and dimMemberID<>0
group by dimMemberID
having sum(AMT)>100 and sum(AMT)<200
order by sum(AMT) desc;
--其次找会员详情
select *
from dw.fct_sales
where dimDateID = '20170702'
and dimMemberID<>0
and dimMemberID in
(select dimMemberID
from dw.fct_sales
where dimDateID = '20170702'
and dimMemberID<>0
group by dimMemberID
having sum(AMT)>100 and sum(AMT)<200
order by sum(AMT) desc);
答案结果:
注意:
1.子查询跟在where 后面,当作一个过滤条件;这个字段是也必须有且只能有一个
2.在子查询中,表是可以不一样的;
例如:在select 可以是其它表的输入,可以与from 后面的表不一样。select * from dw.fct_sales where dimDateID = '20170702' and dimMemberID<>0 and dimMemberID in (select distinct dimMemberID from dw.fct_sales_item where dimDateID = '20170702' and dimMemberID<>0);