leetcode数据库题第七弹
- 1581. 进店却未进行过交易的顾客
- 1587. 银行账户概要 II
- 1633. 各赛事的用户注册率
- 1661. 每台机器的进程平均运行时间
- 1667. 修复表中的名字
- 1683. 无效的推文
- 1693. 每天的领导和合伙人
- 1729. 求关注者的数量
- 1731. 每位经理的下属员工数量
- 1741. 查找每个员工花费的总时间
- 小结
1581. 进店却未进行过交易的顾客
https://leetcode.cn/problems/customer-who-visited-but-did-not-make-any-transactions/
本来想偷懒,直接写个一拖三,但是。。。效率有点吓人的低
select customer_id,count(0) count_no_trans
from visits v
where visit_id not in (select visit_id from transactions t)
group by customer_id
那就换个一拖三的办法
select customer_id,count(0) count_no_trans
from visits v
left join transactions t on t.visit_id=v.visit_id
where t.visit_id is null
group by customer_id
CSDN 文盲老顾的博客,https://blog.csdn.net/superwfei
1587. 银行账户概要 II
https://leetcode.cn/problems/bank-account-summary-ii/
还以为和前边一样,要case一下再 sum ,结果。。。。直接正负数就已经列出来了。。。
Hmmmm。注意,是高于10000,不小心习惯性的写成 >= 运算符,白瞎了一次提交。
select u.name,sum(t.amount) balance
from users u
left join transactions t on u.account=t.account
group by u.account,u.name
having(sum(t.amount)>10000)
1633. 各赛事的用户注册率
https://leetcode.cn/problems/percentage-of-users-attended-a-contest/
额。。。。用子查询求出用户总数作为除数就好,嗯,注意 group 跟的字段,mysql 可以省略一些内容。。。
# mysql
select r.contest_id,round(count(r.user_id)/b.total * 100,2) percentage
from register r,(select count(user_id) total from users) b
group by r.contest_id
order by count(0) desc,r.contest_id
# mssql
select r.contest_id,convert(decimal(6,2),count(0) * 1.0/b.total * 100) percentage
from register r,(select count(0) total from users) b
group by r.contest_id,b.total
order by count(0) desc,r.contest_id
# oracle
select r.contest_id,round(count(r.user_id)/b.total * 100,2) percentage
from register r,(select count(user_id) total from users) b
group by r.contest_id,b.total
order by count(0) desc,r.contest_id
1661. 每台机器的进程平均运行时间
https://leetcode.cn/problems/average-time-of-process-per-machine/
嗯。。。。其实算是行转列类的需求,不过只有两个对应数据,所以,就直接自关联一下就可以了。
# oracle && mysql
select a.machine_id,round(avg(ts),3) processing_time
from (
select a.machine_id,b.timestamp-a.timestamp ts
from activity a
inner join activity b on a.machine_id=b.machine_id and a.process_id=b.process_id
where a.activity_type='start' and b.activity_type='end'
) a
group by a.machine_id
# mssql
select a.machine_id,convert(decimal(6,3),avg(ts)) processing_time
from (
select a.machine_id,b.timestamp-a.timestamp ts
from activity a
inner join activity b on a.machine_id=b.machine_id and a.process_id=b.process_id
where a.activity_type='start' and b.activity_type='end'
) a
group by a.machine_id
说起来,mssql 的保留指定位数的小数,实在有点太恶心了,必须自己指定类型来干掉浮点数多余的小数位
1667. 修复表中的名字
https://leetcode.cn/problems/fix-names-in-a-table/
哦,字符串操作函数也上场了。注意 substr/substring 的写法,以及 concat 的用法,mssql 可以用 + 运算代替 concat,其他的不行
# mssql
select user_id,upper(left(name,1)) + substring(lower(name),2,len(name)) name
from Users
order by user_id
# mysql
select user_id,concat(upper(substring(name,1,1)),substring(lower(name),2,length(name))) name
from users
order by user_id
# oracle
select user_id,concat(upper(substr(name,1,1)),substr(lower(name),2,length(name))) name
from users
order by user_id
1683. 无效的推文
https://leetcode.cn/problems/invalid-tweets/
呵,数据库字符串操作入门题,一个 len/length 足够,还以为会有全角字符,unicode ,结果根本没用上 blen 之类的东西。
# mssql
select tweet_id
from tweets
where len(content)>15
# oracle && mysql
select tweet_id
from tweets
where length(content)>15
1693. 每天的领导和合伙人
https://leetcode.cn/problems/daily-leads-and-partners/
额。。。。简单的 count distinct 即可。。。。oracle 的就不写了,其实指令是一拖三,不过 oracle 需要用 to_char 处理下日期格式,干掉时间部分
select date_id,make_name,count(distinct lead_id) unique_leads,count(distinct partner_id) unique_partners
from dailySales
group by date_id,make_name
1729. 求关注者的数量
https://leetcode.cn/problems/find-followers-count/
额,统计入门题,直接 group count 。。。。。
select user_id,count(0) followers_count
from followers
group by user_id
order by user_id
1731. 每位经理的下属员工数量
https://leetcode.cn/problems/the-number-of-employees-which-report-to-each-employee/
。。。。又是 group ,力扣到底是有多喜欢用 group 啊。。。。无语了
# mysql && oracle
select a.employee_id,a.name,count(0) as reports_count,round(avg(b.age),0) average_age
from employees a
inner join employees b on a.employee_id=b.reports_to
group by a.employee_id,a.name
having(count(0)>0)
order by a.employee_id
# mssql
select a.employee_id,a.name,count(0) as reports_count,convert(int,round(avg(b.age * 1.0),0)) average_age
from employees a
inner join employees b on a.employee_id=b.reports_to
group by a.employee_id,a.name
having(count(0)>0)
order by a.employee_id
1741. 查找每个员工花费的总时间
https://leetcode.cn/problems/find-total-time-spent-by-each-employee/
写了一大堆的 group 了,恶心,想吐,还想吃点酸的。。。。。。。
# oracle
select to_char(event_day,'YYYY-mm-DD') day,emp_id,sum(out_time-in_time) total_time
from employees
group by event_day,emp_id
# mysql && mssql
select event_day day,emp_id,sum(out_time-in_time) total_time
from employees
group by event_day,emp_id
小结
刷了一段时间数据库题,才发现力扣的公共数据库题,一共也才80个题目,这再刷一波,免费题目就刷完了。
整体来说,免费题目简单过头了。。。。刷起来一点成就感都没有,完全没有老顾自己写的那几个row_number 和 cte 实例来的有感觉。
尤其是,目前刷了70个数据库题目,基本上大半都带有 group 操作,实在是。。。。恶心坏了。
也不知道哪个小伙伴,有力扣的会员,让老顾把那些标注为困难级别的数据库题看看。
数了一下,困难级别的数据库题,也一共才 39 个题目,只有三个是公开的题目。
按照题目的名称来看,还是有一大半有 group 需求。。。。
这些题目不好玩,刷完了以后,一点长进都没有。。。。。