数据分析师 MySQL 笔记汇总【一】

数据分析师 MySQL面试题笔试题Leetcode题 笔记汇总

1,连续数 Leetcode 180题

这段代码可以直接记。遇到具体问题把Num改成你要计算的值就可以。

select distinct Num as ConsecutiveNums
from (
  select Num, 
    case 
      when @prev = Num then @count := @count + 1
      when (@prev := Num) is not null then @count := 1
    end as CNT
  from Logs, (select @prev := null,@count := null) as t
) as temp
where temp.CNT >= 3

2,Leetcode 185 部门工资前三员工<判断并列>

-- 第一步 rank() over() as ranking
-- 第二步 取出第三名的salary
-- 第三步 只取大于第三名的salary的
-- 第四步 join获取department.name

with temp as (
    select s.*, rank() over(partition by departmentid order by s.salary desc) as ranking
    from(
        select distinct salary, departmentid
        from employee
    ) as s
)

select d.name as Department, e1.name as Employee, e1.salary as Salary
from department as d
join (
    select e.id, e.name, e.salary, e.departmentid, a.top3_salary
    from employee as e
    join (
        select temp.departmentid, min(temp.salary) as top3_salary
        from temp
        where temp.ranking <= 3
        group by temp.departmentid
    ) as a
    on e.departmentid = a.departmentid
) as e1
on d.id = e1.departmentid
where e1.salary >= e1.top3_salary

3,topN

不要求分类的话,就活用limit N,1

要求分类的话,

select *
from (
   select *, 
          row_number() over (partition by 要分组的列名
                       order by 要排序的列名 desc) as ranking
   from 表名) as a
where ranking <= N

4,连续登录

先用这个day - ranking(由row_number()算出来的)列

CREATE TABLE IF NOT EXISTS `loadrecord` (
  `uid` int(6) unsigned NOT NULL,
  `loadtime` varchar(200) NOT NULL,
  PRIMARY KEY (`uid`,`loadtime`)
) DEFAULT CHARSET=utf8;
INSERT INTO `loadrecord` (`uid`, `loadtime`) VALUES
  ('201', '2017/1/1'),
  ('201', '2017/1/2'),
  ('202', '2017/1/2'),
  ('202', '2017/1/3'),
  ('203', '2017/1/3'),
  ('201', '2017/1/4'),
  ('202', '2017/1/4'),
  ('201', '2017/1/5'),
  ('202', '2017/1/5'),
  ('201', '2017/1/6'),
  ('203', '2017/1/6'),
  ('203', '2017/1/7');

select uid, max(cnt) as cnt
from (
select uid, dd, count(dd) as cnt
from(
	select *,day(loadtime) - row_number() over(PARTITION by uid order by uid,loadtime) as dd
	from loadrecord
) as temp
group by temp.uid,temp.dd
) as cnt
GROUP BY uid

5,留存率

select *,
concat(round(100*次日留存用户/日活跃用户数,2),'%')  次日留存率,
concat(round(100*三日留存用户/日活跃用户数,2),'%')  三日留存率,
concat(round(100*七日留存用户/日活跃用户数,2),'%')  七日留存率
from (
select
        a.log_day 日期,
count(distinct user_id)  日活跃用户数,
count(distinct concat(b.device_id,b.app_id))  次日留存用户,
count(distinct concat(c.device_id,c.app_id))  三日留存用户,
count(distinct concat(d.device_id,d.app_id))  七日留存用户
from user_log a 
left join user_log b on concat(a.device_id,a.app_id) = concat(b.device_id,b.app_id) and b.log_day = a.log_day + 1
left join user_log c on concat(a.device_id,a.app_id) = concat(c.device_id,c.app_id) and c.log_day = a.log_day + 3
left join user_log d on concat(a.device_id,a.app_id) = concat(d.device_id,d.app_id) and d.log_day = a.log_day + 7
group by a.log_day
) p;

select *,
concat(round(100*次日留存用户/日新增用户数,2),'%')  次日留存率,
concat(round(100*三日留存用户/日新增用户数,2),'%')  三日留存率,
concat(round(100*七日留存用户/日新增用户数,2),'%')  七日留存率 
from
(  
select
  c.log_day 日期,
count(distinct concat(c.device_id,c.app_id))  日新增用户数,
count(distinct concat(d.device_id,d.app_id))  次日留存用户,
count(distinct concat(e.device_id,e.app_id))  三日留存用户,
count(distinct concat(f.device_id,f.app_id))  七日留存用户
from
  (
select a.*
from user_log a 
left join user_log b on concat(a.device_id,a.app_id) = concat(b.device_id,b.app_id) and b.log_day < a.log_day
where b.log_day is null
  ) c
left join user_log d on concat(c.device_id,c.app_id) = concat(d.device_id,d.app_id) and  d.log_day = c.log_day + 1
left join user_log e on concat(c.device_id,c.app_id) = concat(e.device_id,e.app_id) and  e.log_day = c.log_day + 3
left join user_log f on concat(c.device_id,c.app_id) = concat(f.device_id,f.app_id) and  f.log_day = c.log_day + 7
group by c.log_day
) p;

6,Leetcode 197题 上升的气温

select a.id
from weather a
left join weather b
on DATEDIFF(a.recorddate, b.recorddate) = 1
where a.temperature > b.temperature

这种类型的题,如何连接才是关键,left join的关键。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值