题23:
根据下表写一段SQL来查找每天仅使用手机端用户、仅使用桌面端用户和同时使用桌面端和手机端的用户人数和总支出金额。
其中:
- 表的主键是:user_id, spend_date, platform;
- 平台列 platform 是一种 ENUM ,类型为:‘desktop’, ‘mobile’。
解题思路:
(1)需要统计每天不同平台的消费额,这时需要根据用户和时间分组;group by user_id,spend_date
;
(2)需要构建一列“platform”其中包含 ‘both’ ‘desktop’ ‘mobile’,由于不存在的字段 ‘both’,这时需要根据条件计算:
if(count(distinct platform)=2,'both',platform)
sum(amount)
(1)(2)步就构建一个子查询a表,代码如下:
(
select spend_date,user_id,
if(count(distinct platform)=2,'both',platform) as platform,
sum(amount) as amount
from spending
group by user_id,spend_date
) a
(3)构造列中如果当日没有同时使用’mobile’和’desktop’购买的用户,就无法输出’both’字段,因此我们需要构造出一个固定输出三个字段 ‘both’ ‘desktop’ ‘mobile’ 的列,则b表如下:
(
select 'desktop' as platform union
select 'mobile' as platform union
select 'both' as platform
) b
(4)通过筛选条件的列按照,spend_date 和 platform 作为分组对total_amount 和 total_user进行统计,由于不需要做表间的连接,则不需要添加三个子查询以日期作为连接条件,在表之间进行筛选就是当 a.platform = b.platform 时统计amount,则父查询的选择列为:
select spend_date,b.platform,
sum(if(a.platform=b.platform,amount,0)) as total_amount,
count(if(a.platform=b.platform,1,null)) as total_users
from(a,b)
group by spend_date,platform;
最终代码:
select spend_date,b.platform,
sum(if(a.platform=b.platform,amount,0)) as total_amount,
count(if(a.platform=b.platform,1,null)) as total_users
from(
select spend_date,user_id,
if(count(distinct platform)=2,'both',platform) as platform,
sum(amount) as amount
from spending
group by user_id,spend_date
) a,(
select 'desktop' as platform union
select 'mobile' as platform union
select 'both' as platform
) b
group by spend_date,platform;