【11】595. 大的国家

select name,population,area
from World
where area > 3000000 or population > 25000000;

Mysql中的科学计数法

【12】197. 上升的温度

select Id
from Weather as we
where Temperature> (select Temperaturefrom Weatherwhere dateDiff(we.RecordDate,Weather.RecordDate)=1)select we.Id
from Weather as we left join Weather as w
on w.RecordDate=date_add(we.RecordDate,interval -1 day)
where we.Temperature>w.Temperature

时间相关函数,摘自:https://www.cnblogs.com/xuelu/p/3770478.html

date_add(@dt, interval 1 day)  -- 在dt时间上 add 1 day
date_add(@dt, interval -1 day); -- 在dt时间上 sub 1 day 减1
adddate()
addtime() --功能类似
date_sub() --减法
subdate()
subtime()datediff(date1,date2) -- date1-date2  返回天数
timediff(time1,time2) -- time1 - time2 返回 time 差值 类似于 08:08:08
--注意:timediff(time1,time2) 函数的两个参数类型必须相同

思考:为什么 不能直接做减法??为什么给出的例子可以通过,但是13个测试用例不行类似于下面这样?

select Id
from Weather as we
where Temperature> (select Temperaturefrom Weatherwhere we.RecordDate-Weather.RecordDate=1)

原因:https://www.cnblogs.com/jxterminator/p/4120850.html

(1)如果直接相减,那么就把时间转换成了 2013-04-21 16:59:33 直接转换为20130421165933,进制会出现问题。从而导致问题。(2)还有就是在类似于'2012-01-01'这样的日期的时候会出现问题,减1不能够实现。还是要利用datediff()来做。

【13】184. 部门工资最高的员工

group by 和where位置关系。

MySQL中没有with as子句来创建,但是可以在from 后面直接写临时表结构,来实现类似功能。

在 Mysql中 s inner join t = s join t = s,t ,都是内连接的方式。这道题要注意内连接和left join的区别。因为内连接中where两端都不能为空,因此不会出现 Department's Name is null 的情况。但是 left join 在on时,找不见条件,也会保留左表内容,因此会出现  Department's Name is null 的情况,最后要用where 语句剔除掉这种情况。

select de.Name as Department,t.Name as Employee ,t.Salary --left joinfrom (select e.Name,e.DepartmentId,e.Salaryfrom Employee as ewhere Salary=(select max(Salary) from Employeewhere e.DepartmentId=DepartmentId)  ## 临时表t) as t left join Department as de on t.DepartmentId =de.Idwhere de.Name is not null   --临时表查询 写在 where这个where 中 等效 
select de.Name as Department,e.Name as Employee, e.Salary  -- inner join
from Employee as e,Department as de
where e.DepartmentId=de.Id  and e.Salary=( -- 内嵌相关子查询select max(Salary)from Employeewhere e.DepartmentId = Employee.DepartmentId)

官方解答: in 可以同时判断两个列的情况

where (a,b) in (select a,bfrom table_name)

先找出 部门id,和部门最大工资。然后再利用in 内联表中id 和 salary是否对应。从而找到部门最大工资和id。

select de.Name  as Department,ee.Name as Employee,ee. Salary
from Employee as ee,Department as de
where ee.DepartmentId=de.id and (ee.DepartmentId,ee.Salary) in (select DepartmentId,MAX(Salary)from EmployeeGROUP BY DepartmentId )

【14】626. 换座位

(1)利用 union 来做

select a.id,a.student
from (select id-1 as id ,student ## 偶数均减1 from seat where id mod 2=0union select id+1 as id,student ##奇数不一定都加1from seat where id mod 2 =1 and id <> (select(max(id)) from seat)unionselect id,studentfrom seatwhere id mod 2 =1 and id=(select(max(id)) from seat)) as a
order by a.id

(2)利用case when语句 来自:@blacksheep

select (case when id mod 2=1 and id =(select max(id) from seat ) then id --顺序不能调换when id mod 2=1 then id+1 -- 顺序不能调换else id-1end ) as id,student
from seat
order by id;

其中包含一个case ..when的知识点在于...他是if elif else 的结构,而不是 if else if else结构。也就是说,当此条件通过的时候,它就执行了,不会再继续执行下面判断。因此 id mod 2=1 and id =(select max(id) from seat ) then id 和 when id mod 2=1 then id+1 不能调换位置。 使用过程中应该注意这个点。https://blog.csdn.net/QQ826688096/article/details/89242180

(3)利用 if(exp1,exp2,exp3)来做。可以在任意位置 利用 if(exp1,exp2,exp3)。

select (if (mod(id,2),if(id=(select max(id) from seat),id,id+1),id-1) )  as id,student
from seat
order by id 

【15】177. 第N高的薪水

mysql function的基本结构:https://blog.csdn.net/jssg_tzw/article/details/39694489  高级查询的时候才会用到这种形式

CREATE FUNCTION func_name(input input_type) RETURNS output_type
BEGINset N = n-1; ##set is not in return ## could add if -elseRETURN ( write SQL ); if expression then return NULL;    else return (); ## return end if; ## if END ## Begin

(1)用distinct 实现

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGINSET n = N-1 ##参数位置RETURN (     SELECT DISTINCT Salary FROM Employee ORDER BY Salary DESC LIMIT n,1 ); ## 用distinct 先筛选后,然后去第N高
END

但是有个问题, N=-1时,limit能过么??

(2)先找出前N高的所有数据,然后返回N高中最小的。

知识点:if(exp1,exp2,exp3)表达式不仅可以直接用select语句,还可以直接用from 里面的 列变量。

count(*)和count(1)的区别:https://www.cnblogs.com/xiaozengzeng/p/12078845.html

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGINRETURN (     SELECT  IF(count<N,NULL,min) FROM(SELECT MIN(Salary) AS min, COUNT(1) AS countFROM(SELECT DISTINCT SalaryFROM Employee ORDER BY Salary DESC LIMIT N) AS a) as b);
END

上面两种方案都来自:https://leetcode-cn.com/problems/nth-highest-salary/solution/liang-ge-hao-li-jie-de-fang-an-by-postor/

【16】262. 行程和用户

知识点:(1)别名处的空格处理(利用的转义字符):https://www.cnblogs.com/end/archive/2011/04/01/2002516.html

可以直接用' '来就行。里面可以识别空格。

(2)单引号和双引号的区别:https://www.cnblogs.com/xuhaojun/p/9145581.html

https://blog.csdn.net/menghuanzhiming/article/details/77017137

(3)sum() count() 等用法。

count()和 sum() 都是聚合函数,可以与group by一起使用。由于 group by 是按照 某一个列进行分组,分组之后每个组内的情况不相同 ,count()等函数都是作用在任一分组上的。他可以计算组内的情况。

sum(if (c.STATUS = 'completed',0,1))

sum()函数分别遍历组内的每个status,直到每个分组都结束。返回的个数是分组之后的个数。

id request_at/sum() status
1
2
'2013-10-01'/每个组返回一个sum() completed 
canceled_users
3 '2013-10-2' canceled_dirver
4 completed

这里也可以解释where为什么必须在group by函数前面。where筛选的是某一行,但是group by之后,不再是每一行单独存在了。所以where要在前面。如果放在后面,有行已经按照分组合并在了一起了,where并不能剔除某一行。having呢?就是作用于分组的,它的作用其实类似于count()和 sum(),只不过他是筛选分组条件。此外where和having两者不冲突。

我的题解(不对的):

select a.Request_at as Day, round((a.called/b.all_),2) as 'Cancellation Rate'
from(select t.Request_at,count(t.Status) as calledfrom Trips as t join Users as u on t.Client_Id=u.Users_Id and u.Banned='No'where t.Request_at between '2013-10-01' and '2013-10-03'  and t.Status<>'completed 'group by t.Request_at) as a join ( select t.Request_at,count(t.Status) as all_ from Trips as t join Users as u on t.Client_Id=u.Users_Id and u.Banned='No' where t.Request_at between '2013-10-01' and '2013-10-03' group by t.Request_at ) as b on a.Request_at=b.Request_at
order by a.Request_at

问题:(1)没有考虑到用户表不是严格的用户,统计的应该是司机和用户都是非禁止的用户才行

(2)利用join 将  a 和b 表连接的时候,会出现丢失日期的问题,因为可能存在一些日期只有 非禁止用户总量而没有取消订单的情况。

(3)没有有效的利用 除了 statu之外的条件,不会将count()函数灵活运用

(4)连接过程,出现问题。刚开始使用的 left join而不是 join。用left join 会出现左表的内容会全部保留的情况。导致count()计算出现问题。所以 要注意到底是用join还是 left join。

题解1:

巧妙的用了avg函数。求解平均数。统计每个分组中  t.Status 中 等于'completed' 和 不能等于 'completed' 的。

假设 不等于'completed' 有10个,等于'completed' 有5个,那么平均值:(10*1+0*5)/(10+5) 将count()转换成了0和1。带了一个条件判断。

select t.Request_at as Day, round(avg(t.Status<>'completed '),2) as 'Cancellation Rate'
from Trips as t join Users as u on (t.Client_Id=u.Users_Id and u.Banned ='No') join Users as us on t.Driver_Id=us.Users_Id  and us.Banned='No'
where t.Request_at between '2013-10-01' and '2013-10-03'
group by t.Request_at
order by t.Request_at

题解2:

参考连接中题解2的方法,修改我的。(修改完发现逻辑一样)

select c.Request_at as Day,round(sum(if (c.STATUS = 'completed',0,1))/count(c.STATUS),2) as 'Cancellation Rate'
from(select t.Request_at,t.Statusfrom Trips as t join Users as u on t.Client_Id=u.Users_Id and u.Banned='No'join Users as us on t.Driver_Id=us.Users_Id and us.Banned='No' ## 修改第一问题where t.Request_at between '2013-10-01' and '2013-10-03'
)  c
group by c.Request_at
order by c.Request_at

【17】178. 分数排名

rank()是一个窗口函数,详情可以看:https://leetcode-cn.com/problems/rank-scores/solution/tu-jie-sqlmian-shi-ti-jing-dian-pai-ming-wen-ti-by/

解题思路来自: 链接1.

select a.Score,(select count(distinct b.Score) from Scores as b where b.Score>=a.Score
) as 'Rank'
from Scores as a
order by Score desc 

先按照成绩排序,然后再给每个成绩计算一个名次,如何计算?那么就是有多少个比现在分数高的,那么它就位于哪个名次。有两个比他高的+他自己,那么他就是第三名。

【18】601. 体育馆的人流量

我的题解:思路就是每个id后面,跟四个值。因为连续三个,可以是(id-2,id-1,id)(id-1,id,id+1) (id,id+1,id+2)三种状态。只要有一个满足条件就行。注意的是,子查询的条件 (id=a.id+1)。

select st.id,st.visit_date,st.people
from (select a.id,a.visit_date,a.people,(case when a.id+1<=(select max(id) from stadium) then (select people from stadium where id=a.id+1) else null end ) as after_1,(case when a.id+2<=(select max(id) from stadium) then (select people from stadium where id=a.id+2) else null end) as after_2,(case when a.id-1>=1 then (select people from stadium where id=a.id-1) else null end) as before_1,(case when a.id-2>=1 then (select people from stadium where id=a.id-2) else null end) as before_2
from stadium as a
where a.people>=100) st
where  (st.after_1 >=100 and st.after_2>=100)  or (st.after_1>=100 and st.before_1 >=100)  or (st.before_1>=100 and st.before_2>=100)

官方题解:找id符合的,但是官方题解,先做了一个三表连接。将people>=100的所有id组合列出,然后按照 第一天是高峰,第二天是高峰,第三天是高峰,来排除id保留最后结果。假设s1为高峰期,s1可以在第一天出现,第二天出现以及第三天出现。

select distinct s1.id,s1.visit_date,s1.people
from  stadium s1,stadium s2,stadium s3
where s1.people>=100 and s2.people>=100 and s3.people>=100 and ((s1.id = s2.id-1 and s1.id = s3.id-2 and s2.id=s3.id-1) or (s2.id=s1.id-1 and s2.id=s3.id-2 and s1.id = s3.id-1)  or (s1.id = s2.id+2 and s1.id=s3.id+1 and s2.id=s3.id-1))
order by s1.id
--  s1,s2,s3   s2,s1,s3  s2,s3,s1

窗口函数的做法 来自评论@whisperloli:

SELECT  id,visit_date,people ------/* Write your T-SQL query statement below */
FROM    (SELECT  id,visit_date,people,COUNT(*) OVER(PARTITION BY rn) AS cntFROM    (SELECT  *,(id - row_number() OVER(ORDER BY id)) AS rnFROM    stadiumWHERE   people >= 100) a) d
WHERE   cnt >= 3 ;

(1)内层用一个row_number计数函数,将rn 分成几个部分。因为 如果连续三个的话,那么利用 id-row_number应该是相同值。比如 id= 2,3,4,7,8,10  row_number = 1,2,3,4,5,6 id-row_number() = 1,1,1,3,3,4。从而就可以找见连续的区间中的id都实哪些。 -> where 和 窗口函数的先后关系是,先利用where筛选后,才会利用窗口函数。窗口函数和select 是同一层级。

(2)外层函数中 按照 rn分区,然后找到分区个数内>=3的,那么就是这个rn中至少包含三个连续的。

最后将这些id找出,即可。

【19】185. 部门工资前三高的所有员工

窗口函数的做法:

/* Write your T-SQL query statement below */
select de.NAME Department,a.nAME Employee,a.Salary
from (select Name,DepartmentId,Salary,dense_rank() over(partition by DepartmentId order by Salary desc ) as row_nofrom Employee
) a join Department de on a.DepartmentId=de.Id
where a.row_no<=3

来自评论:@高斯恍惚  对于前N个问题,都可以这样做。

select d.Name as Department,e.Name as Employee,e.Salary as Salary
from Employee as e inner join Department as d
on e.DepartmentId = d.Id
where e.Id in
(   -- 做自连接,保存比自己工资高的和员工,按照id分组,如果比自己高的不同工资个数小于等于2,-- 那么我就在前三中,将id筛选后,再做一层连接select e1.Idfrom Employee as e1 left join Employee as e2on e1.DepartmentId = e2.DepartmentId and e1.Salary < e2.Salarygroup by e1.Idhaving count(distinct e2.Salary) <= 2
)
order by d.Id asc,e.Salary desc

【20】180. 连续出现的数字

我的题解:

select distinct Num as ConsecutiveNums
from Logs as lo
where Num = (select Numfrom Logs as l1where lo.id +1 = l1.id
) and Num=(select Numfrom Logs as l2where lo.id+2=l2.id
)

问题:如果是连续出现10次那么id怎么写?要连续加么?

评论连接中@山水有相逢2333给出了解决方法。

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

利用了sql的 用户变量。

一共有两种用户变量的赋值方法。 https://blog.csdn.net/weixin_42373127/article/details/88909982

set的使用方法:
set @变量名 {= | := } value [,@变量名 {= | := } value,…] ;select的使用方法:
select :=

上面利用用户变量的意思逻辑整理如下:

 prev = null count=null --初始化 if prev = num then count +=1 --继续看下一条else: prev= num count =1 --初始计算 第一次接触用户变量
相当于 L = [1,1,12,1,2,2]prev = 0,count=0for i in range(0,len(L)):if prev = L[i]:count+=1else:prev = L[i]count = 1if count >=3:print(L[i])

Leetcode SQL 刷题 Mysql【2】相关推荐

  1. LeetCode SQL 刷题

    文章目录 MySQL配置 数据库准备 1. 大国 2. 换座位 2.1 solution-1 2.2 solution-2 3. 交换工资 solution-1 4. 有趣的电影 solution 5 ...

  2. 牛客网SQL刷题笔记(MySQL)

    牛客网SQL刷题笔记(MySQL) 此博客集合LeetCode.牛客网常见的题型及其解法,侵删 目录 牛客网SQL刷题笔记(MySQL) 类型1:查找排名第几的数据 SQL2 查找入职员工时间排名倒数 ...

  3. SQL刷题记录(一)

    SQL刷题记录(一) 答主刚开始自学SQL,本专栏记录的是答主在牛客上刷题的过程.疑惑和部分思路都会写在习题下方. 题目来源:牛客网刷题网址 本文内容:T195-T225 T195. select * ...

  4. 【Leetcode】 刷题之路1(python)

    leetcode 刷题之路1(python) 看到有大佬总结了一些相关题目,想着先刷一类. 1.两数之和 15.三数之和 16.最接近的三数之和 11.盛最多的水 18.四数之和 454.四数相加II ...

  5. leetcode每日刷题计划-简单篇day8

    leetcode每日刷题计划-简单篇day8 今天是纠结要不要新买手机的一天QAQ想了想还是算了吧,等自己赚钱买,加油 Num 70 爬楼梯 Climbing Stairs class Solutio ...

  6. 「数据库」sql刷题(No.11)

    喜欢就 关注 我们吧! 简介:  Hello 各位 ,我是公号「八点半技术站」的创作者 - Bruce.D (姓氏:豆). 感谢微信给予的个人认证,专注于PHP.Go.数据库技术领域知识经验分享. 技 ...

  7. LeetCode代码刷题(17~24)

    目录 17. 电话号码的字母组合 18. 四数之和 19. 删除链表的倒数第 N 个结点 20. 有效的括号 21. 合并两个有序链表 22. 括号生成 23. 合并K个升序链表 24. 两两交换链表 ...

  8. leetcode分类刷题笔记

    leetcode分类刷题笔记--基于python3 写在前面 1.做题如果实在想不出时间复杂度比较优的解法,可以先写出暴力解法,尝试在其基础上优化 2.排序.双指针.二分等--经常可以优化时间复杂度 ...

  9. 【SQL刷题】DAY16----SQL高级联结专项练习

    博主昵称:跳楼梯企鹅 博主主页面链接:主页传送门 博主专栏页面连接:网络安全专栏传送么门 创作初心:本博客的初心为与技术朋友们相互交流,每个人的技术都存在短板,博主也是一样,虚心求教,希望各位技术友给 ...

最新文章

  1. android 添加头参数,Retrofit添加header参数的几种方法
  2. .NET中的IO操作之文件流
  3. 皮一皮:高手。。。真是高手
  4. 解决域中打印机不能共享打印的问题
  5. Windows 怎么了?微软又停止一大版本更新
  6. lucene(全文搜索)_建立索引_根据关键字全文搜索_源码下载
  7. case / switch语句的Python等价物是什么? [重复]
  8. 推荐一款ORM工具 FOR ADOBE AIR
  9. 【Android】 修复ijkPlayer进行m3u8 hls流播放时seek进度条拖动不准确的问题
  10. 学习笔记 | 读完《公开募集证券投资基金销售机构监督管理办法》的几点感受
  11. STM32连接摄像头知识积累
  12. Android动画插入器
  13. python基于flask_sockets实现WebSocket
  14. Mysql循环插入语句
  15. A1333:具有安全关键应用集成诊断功能的精密、高速、霍尔效应角度传感器 IC
  16. VC API常用函数简单例子大全(1-89)
  17. Spring IOC与DI、反射的理解 含小案例说明
  18. 休闲卤味的商业江湖里,周黑鸭的巨变与出路
  19. java基础 —— 集合、异常、反射、io流、多线程
  20. Vue 中使用 axios 传输数据,当数据量过大时会提示跨域?(√已解决)

热门文章

  1. 使用uwolfer gerrit-rest-java-client获取Gerrit信息
  2. SpringBoot整合Spring Security【超详细教程】
  3. python解/压缩文件夹到指定位置
  4. python语料处理_Python中文语料批量预处理手记
  5. 工程热物理类毕业论文文献有哪些?
  6. 映像劫持技术(1):简单介绍
  7. 2010最流行中秋祝福短信
  8. textContent 和 innerText 之间的区别
  9. 聊城大学格创计算机协会干事纳新工作取得圆满成功
  10. 第一次搭建成功MySQL数据库