周一傍晚跑步,王城大道的天桥上,偶遇一个高三的小姑娘在那儿拿着卷子站在天桥上的角落里不知道背些什么,顿时心里一阵翻涌。或许在许多城市的许多隐蔽的角落,都藏着一个个小小的梦想。年轻人们,好好学吧,无论做什么,今天在家多学一门技术,明天出去少一句求人的话。
题目链接: 点击传送至本题
题目大意:
有World表(name,continent ,area,population,gdp)
,关于大国的定义是面积超过300万平方公里或人口超过2500万。现在要求查出其中大国的(name,population,area)信息。
解题思路:
方法1:
此题较容易,可以在where限定语句后配合or来完成两个筛选条件的连接。
方法2:(优)
此题虽容易,但为了提高效率可以使用union替代or。在这里union的效率会比or的速度更快。
# 595. 大的国家
# 方法1:
select name,population,area
from World
where area>3000000 or population>25000000;
# 方法2(优)
select name,population,area
from World
where area>3000000
union
select name,population,area
from World
where population>25000000;
题目链接: 点击传送至本题
题目大意:
有courses表(student,class),要求查询出选课人数大于等于5的课程。
解题思路:
方法1:
提取出一个包含课程字段、每个课程的选课人数的字段 的临时表,然后在此临时表上添加where筛选条件。需要注意的是每个课程的选课人数使用count(student)配合group by class
来完成,由于此题测试用例中包含重复数据,如学生A选了两次某课程,所以还需要添加distinct来去重。
方法2:(优)
方法1使用临时表是因为count(student)不能直接在where子句中使用,方便为count(student)重命名,这种方法完全可以,但是存在更优的方案,即使用having替换where
。
# 596. 超过5名学生的课
# 方法1:
select class from(
select class,count(distinct student) as "num"
from courses
group by class
) as temp_table
where num>=5;
# 方法2:(优)
select class
from courses
group by class
having count(distinct student)>=5;
题目链接: 点击传送至本题
题目大意:
有电影表cinema( id,movie,description,rating)
,要求查出影片描述(description字段)不是boring且id为奇数的影片,结果按照登记rating降序排序。
解题思路:
影片描述description字段不是boring,可以使用运算符<>,id为奇数可以使用mod取余运算。
# 620. 有趣的电影
select *
from cinema
where description <> 'boring' and mod(id,2)=1
order by rating desc;
题目链接: 点击传送至本题
题目大意:
有salary(id,name,sex,salary)
表,其中的sex字段中m代表男性,f代表女性。要求:只使用一个更新(Update)语句且不适用临时表,将所有的f和m值交换。
解题思路:
方法1:
使用if语句设置sex字段,如果字段等于f则替换为m,否则替换为f。
方法2:(优)
使用case语句设置sex字段,相比于使用if的方法,case效率更高一点,有空间换时间的意思。
# 627. 交换工资
# 方法1:
update salary
set sex=if(sex='f','m','f');
# 方法2:
update salary
set sex = case
when 'm' then 'f'
else 'm'
end;
题目链接: 点击传送至本题
题目大意:
有Department(id,revenue,month)
表,要求:编写一个sql查询重新格式化表,使得新的表中有一个部门id列和一些对应每个月的收入(revenue)列,新表如下所示:
解题思路:
使用case语句在revenue中筛选对应的月份的revenue 作为Month_Revenue,对每一个月份都进行筛选,通过group by可以实现对相同列进行合并处理。另外,之所以使用聚合函数sum是因为case语句筛选时,除了筛选成功的那个数据,其他数据都会查询为null,返回结果会为多条,聚合函数可以解决这一问题,除了sum,max,min等都可以解决这一问题。
# 1179. 重新格式化部门表
select id,
sum(case when month='Jan' then revenue end) as Jan_Revenue,
sum(case when month='Feb' then revenue end) as Feb_Revenue,
sum(case when month='Mar' then revenue end) as Mar_Revenue,
sum(case when month='Apr' then revenue end) as Apr_Revenue,
sum(case when month='May' then revenue end) as May_Revenue,
sum(case when month='Jun' then revenue end) as Jun_Revenue,
sum(case when month='Jul' then revenue end) as Jul_Revenue,
sum(case when month='Aug' then revenue end) as Aug_Revenue,
sum(case when month='Sep' then revenue end) as Sep_Revenue,
sum(case when month='Oct' then revenue end) as Oct_Revenue,
sum(case when month='Nov' then revenue end) as Nov_Revenue,
sum(case when month='Dec' then revenue end) as Dec_Revenue
from Department
group by id;
题目链接: 点击传送至本题
题目大意:
有座位表seat(id,student)
,要求写出查询语句,改变相邻两个学生的座位。如果学生人数是奇数,则不需要改变最后一个同学的座位。
解题思路:
使用case语句,针对座位id是奇数的同学,修改id为+1,需额外考虑如果最后一个座位id是奇数时,不做修改;针对座位id是偶数的同学,修改id为-1。最后一个座位id的奇偶性可以使用count(*)来判断。全部完成之后,再使用升序将所有的数据重新排列。
# 626. 换座位
select (case
when mod(id,2) = 0 then id - 1
when mod(id,2) = 1 and id = (select count(*) from seat) then id
else id +1
end) as id,student
from seat
order by id asc;
题目链接: 点击传送至本题
题目大意:
有stadium表(id,visit_date,people)
,关于高峰期的定义是连续三行记录中的人流量不少于100,要求编写查询语句,找出人流量的高峰期。
解题思路:
本题不难,只是较为复杂。查找人流量的高峰期有两个重要的条件:①连续三天
:连续三天可以通过自连接两次,形成三张表的笛卡尔积,筛选时可以a表为例,让a分别作为第一天、第二天、第三天,这样才可以考虑完整的情况。②人流量大于等于100
:让三张表的people字段分别大于等于100。
注意:在最后除了要对查询的字段添加distinct进行去重外,还需要对数据进行增量排序。
# 601. 体育馆的人流量
select distinct a.*
from
stadium as a,
stadium as b,
stadium as c
where a.people>=100 and b.people>=100 and c.people>=100
and ((a.id+1 = b.id and b.id+1 = c.id)
or (b.id+1 = a.id and a.id+1 = c.id)
or (b.id+1 = c.id and c.id+1 = a.id))
order by a.id asc;
到这里,LeetCode上可以免费刷的数据库相关的题目就完毕了,接下来我会更新一波数据结构和算法相关的题目,等把免费的再刷完了(如果可以的话),到时候再开LeetCode会员刷会员题。