【LeetCode数据库】 题目总结——经典题目题解与分析(五)--中等难度

刷完了简单难度的数据库题目,对sql中的一些语法特性有了简单的了解,算是学会了挺多思路,还有很多的小技巧

总之就是感觉使用sql能完成的任务越来越多了,能解决的业务场景也也越来越复杂了。有许多之前不得不拿到程序中才能处理的数据使用简单的sql就能够达成,当事人就很有成就感。

所以刷题整理这个过程还会持续下去,从这篇博文开始,就是中等难度的了,由于题目较长或者题解较简单稍微复杂。所以为了避免每篇博文过于冗长,暂定是5-6道题一篇。会挑选博主觉得比较有意义的题目(根据博主不算高的水平)

往期的题解会放在最后,刷题总结会持续更新,来关注博主一起进步啊~


当选者

题目链接
在这里插入图片描述在这里插入图片描述
这道题比较简单,可以算作热身题

题目需要我们统计当选者,即获得投票最高的人。

题目保证了其中最高票数的人仅有一人

于是我们可以先试用子查询查询出获得票数最多的那个人的id

然后再从参选者当中选出那个人的名字

select
    name
from 
    candidate
where 
    id in (
        select(
        select
            candidateid
        from 
            vote
        group by
            candidateid
        order by    
            count(id) desc
        limit 0,1)
    )

2016年的投资

题目链接
在这里插入图片描述
在这里插入图片描述
这道题需要我们统计2016年的投资,但是有效投资需要满足两个条件:

  • 2015年的投资数必须有同年相同资金的投资
  • 该笔投资的地点(经纬度)必须独一无二

所以我们使用子查询分别筛选出满足这两个条件的子集,在where条件中使用in语句进行筛选两个集合的交集即可。

判断15年有没有投资数量一样的投资,我们可以使用自联结,条件就是投资金额一样,这样一来,所有没有相同数目的投资都被筛选掉了,剩下的都是具有相同额度的投资。需要注意的就是一条记录不要联结自己,自己同自己的投资金额一定是相同的,联结记录自己没有意义。

筛选经纬度独一无二的记录也不难办到,我们可以借鉴上面的经验,使用自联结。但是那样我们筛选出来的具有重复经纬度的记录。那我们不妨将表格按照经纬度两个关键字进行分组,之后所有组中元素数量为1的组就是独一无二的。

select
    round(sum(tiv_2016),2) as tiv_2016
from 
    insurance
where 
    pid in (
        select 
            distinct i1.pid
        from 
            insurance i1
            join insurance i2 on i1.tiv_2015 = i2.tiv_2015 and i1.pid != i2.pid
    )
    and pid in(
        select  
            pid
        from 
            insurance
        group by
            lat,lon
        having 
            count(pid) = 1
    )
;

平面上的最近距离

题目链接
在这里插入图片描述
这道题在简单题目中有一道兄弟题目:直线上的最近距离

在这道题中,点的分布从一条直线变成了一个平面。本质上并没有变化,只不过是关键字从一个变成了两个,距离的计算公式发生了变化。

我们使用自联结将每个节点同非自己的节点相联结,并计算出其间距离,按照距离排序取最小即可。

select
    round(sqrt(pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2)),2) as shortest
from 
    point_2d p1
    join point_2d p2 on p1.x != p2.x or p1.y != p2.y
order by
    pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2) 
limit 0,1
;

树节点

题目链接
在这里插入图片描述在这里插入图片描述
这道题需要我们找出所有树的节点的类型,其可能是根、叶子、节点。

一个朴素的想法是使用自联结将这个树结构联结起来,然后根据id进行分组,再从联结表的内容来判断其内容。

不难发现,是那种节点有如下特性:

  • 根没有父节点,父节点p_id是null
  • 节点具有子节点,对子节点的计数值应该大于0
  • 剩下的都是叶子节点

所以我们分好组,使用case-when语句判断这些情况就可以啦。

select
    distinct t1.id,
    (
        case
            when t1.p_id is null then 'Root'
            when count(t2.p_id) > 0 then 'Inner'
            else 'Leaf'
        end
    ) Type
from 
    tree t1
    left join tree t2 on t1.id = t2.p_id
group by
    t1.id
;

好友申请II:谁拥有最多的好友

题目链接
在这里插入图片描述
这道题,需要我们统计哪个用户拥有最多的好友。

有一点需要注意的是,申请添加好友的双方都会各自有一位好友,所以一个人的好友数是其在请求放和接收方出现次数的总和。

所以我们先将所有在申请方和接收方的用户id给查询出来,再按照id进行分组,最后输出那个最高的人就行了。

拼接申请方和接收方的时候可以使用到union,但是需要注意的是,union会对数据进行去重,这是我们不希望的,所以在这道题里面,要用union all!!

select 
    id,
    count(*) as num
from (
    select
        requester_id id
    from 
        request_accepted

    union all

    select  
        accepter_id id
    from 
        request_accepted
) tab
group by
    id
order by 
    count(*) desc
limit 0,1
;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二天 1、查询客户表,统计每个机构2000年之前开户数、2000~2005开户数(含头不含尾)、2005~2010开户数(含头不含尾)、2010之后开户数 展示字段:机构号、2000年之前开户数、2000~2005年开户数、2005~2010年开户数、2010年之后开户数 2、查询客户表,按年份统计,每年、每个机构开户数占全年开户数的占比 展示字段:年份、机构号、开户数、开户占比百分比(百分比) 3、统计所有客户的客户号、存款账户数、2011.12.31日的存款余额、2011.12存款月日均、贷款账户数、2011.12.31日的贷款余额、2011.12贷款月日均 备注:null置为0 第三天 1、统计所有客户的2011.12.31日的存款余额、存款比上日余额、存款比上月余额、、存款比上年余额 备注:存款比上日余额 = 2011.12.31日的存款余额-2011.12.30日的存款余额 存款比上月余额 = 2011.12.31日的存款余额-2011.11.30日的存款余额 存款比上年余额 = 2011.12.31日的存款余额-2010.12.31日的存款余额 只有2011.12.31这个日期可以写死,其他日期要通过2011.12.31这个日期来生成。 2、统计所有2011年存款年日均大于100的客户号、客户名称、存款账户数、2011年年日均 第四天 1、统计所有2011年存款年日均和2011年贷款年日均都大于100的客户号、存款账户数、2011年存款年日均、贷款账户数、2011年贷款年日均 2、统计所有客户的客户号、 存款标志(有存款账户的客户置为1、没存款账户的客户置为0)、 贷款标志(有贷款借据的客户置为1、没贷款借据的客户置为0)、 存款质量分类(2011年存款年日均>=10000置为优质、2011年存款年日均>=1000<10000 置为良好、2011年存款年日均=10000置为优质、2011年贷款年日均>=1000<10000 置为良好、2011年贷款年日均<1000置为普通)、 2011年贷款年日均 第五天 1、根据《事件表.xlsx》来建表,然后将excel中的数据导入到目标表中 2、根据客户表、存款信息表、事件表,统计每个客户2017年的客户号、 交易账户数(客户下有多少个账户有交易就是多少)、 当年有交易的天数(如果2017年有5天有过交易,则有交易天数为5)、 当年有交易总月数(如果2017的1、3、5月有交易,则有交易总月数为3)、 最大的月交易总金额(按月统计交易金额,存放最大的月交易金额)、 最大月交易金额的月份(按月统计交易金额,存放交易金额最大的月份)、 年总交易金额、 年交易金额排名(按客户排名,如果总交易金额为0,则不参与排名,排名置为9999)、 年总手续费、 年总手续费排名(按客户排名,如果总手续费为0,则不参与排名,排名置为9999)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值