数据库练习题(牛客网sql入门篇部分)
Posted 霏ིྀ宇ིྀ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库练习题(牛客网sql入门篇部分)相关的知识,希望对你有一定的参考价值。
数据库练习题
SQL1:查询结果去重
去重关键字 DISTINCT
select DISTINCT university
from user_profile;
group by 是分组查询
SELECT university
FROM user_profile GROUP BY user_profile;
SQL2:查询结果限制返回行数
select device_id
from user_profile
limit 0,2
select device_id
from user_profile
limit 2;
select device_id
from user_profile
limit 2 offset 0;
select device_id
from user_profile
where id in(1,2);
select device_id
from user_profile
where id <=2;
或where id <3;
select device_id
from user_profile
where id=1 or id=2;
SQL3:将查询后的列重新命名
select device_id as user_infos_example
from user_profile
limit 2
select device_id as user_infos_example
from user_profile
limit 0,2
select device_id as user_infos_example
from user_profile
where id in(1,2);
SQL4:查找学校是北大的学生信息
SELECT device_id,university
FROM user_profile
WHERE university LIKE '北京大学%'
SELECT device_id,university
FROM user_profile
WHERE university="北京大学"
SQL5:查找年龄大于24岁的用户信息
select device_id,gender,age ,university
from user_profile
where age>24
SQL6:从不订购的客户
select c.Name as Customers
from Customers c
where c.Id not in (select distinct o.CustomerId from Orders o);
SQL7查找某个年龄段的用户信息
select device_id,gender,age
from user_profile
where age >=20 and age <=23;
select device_id,gender,age
from user_profile
where age between 20 and 24
SELECT device_id,gender,age
from user_profile
where age between 20 and 23
SQL8 查找除复旦大学的用户信息
select device_id,gender,age,university
from user_profile
where university not in ('复旦大学');
select device_id,gender,age,university
from user_profile
where university != '复旦大学';
select device_id,gender,age,university
from user_profile
where university <> '复旦大学';
SQL10 用where过滤空值练习
过滤空值的三种方法:
(1) Where 列名 is not null
(2) Where 列名 != ‘null’
(3) Where 列名 <> ‘null’
SELECT device_id,gender,age,university
FROM user_profile
where age is not NULL
SELECT device_id,gender,age,university
FROM user_profile
where age <>'null' 正则
SELECT device_id,gender,age,university
FROM user_profile
where age !='null' 比较
SQL11 高级操作符练习(1)
现在运营想要找到男性且GPA在3.5以上(不包括3.5)的用户进行调研,请你取出相关数据。
SELECT device_id, gender, age, university,gpa
FROM user_profile
WHERE gpa >3.5 AND gender in('male')
SELECT device_id,gender,age,university,gpa
FROM user_profile
WHERE gpa>3.5 AND gender IN(SELECT gender FROM user_profile WHERE gender='male')
SQL12 高级操作符练习(2)
题目:现在运营想要找到学校为北大或GPA在3.7以上(不包括3.7)的用户进行调研,请你取出相关数据(使用OR实现)
select device_id,gender,age,university,gpa
from user_profile
where gpa>3.7 or university='北京大学';
select device_id,gender,age,university,gpa
from user_profile
where university in('北京大学') || gpa >3.7
SQL13 Where in 和Not in
题目:现在运营想要找到学校为北大、复旦和山大的同学进行调研,请你取出相关数据。
SELECT device_id,gender,age,university,gpa
FROM user_profile
WHERE university IN ("北京大学","复旦大学","山东大学")
select device_id,gender,age,university,gpa
from user_profile
WHERE university="北京大学" or university="复旦大学" or university="山东大学"
select device_id,gender,age,university,gpa
from user_profile
where find_in_set(university,'北京大学,复旦大学,山东大学');
SQL14 操作符混合运用
题目:现在运营想要找到gpa在3.5以上(不包括3.5)的山东大学用户 或 gpa在3.8以上(不包括3.8)的复旦大学同学进行用户调研,请你取出相应数据
SELECT device_id,gender,age,university,gpa
FROM user_profile
user_profile where gpa > 3.8 and university = '复旦大学'
UNION
SELECT device_id, gender, age, university,gpa
from user_profile
where gpa > 3.5 and university = '山东大学'
SELECT device_id, gender, age, university,gpa
from user_profile
where (gpa > 3.8 and university = '复旦大学') or (gpa > 3.5 and university = '山东大学')
#法1:使用 OR 和 AND 混合运算
SELECT device_id,gender,age,university,gpa
FROM user_profile
WHERE gpa>3.5 AND university='山东大学' OR gpa>3.8 AND university='复旦大学'
#法2:使用union all(需要排序)
SELECT device_id,gender,age,university,gpa
FROM user_profile
WHERE gpa>3.5 AND university='山东大学'
UNION ALL
SELECT device_id,gender,age,university,gpa
FROM user_profile
WHERE gpa>3.8 AND university='复旦大学'
ORDER BY device_id ASC
SQL15 查看学校名称中含北京的用户
题目:现在运营想查看所有大学中带有北京的用户的信息,请你取出相应数据。
select device_id,age,university
from user_profile
where university LIKE '%北京%';
SELECT device_id,age,university
FROM user_profile
WHERE university regexp "北京";
LIKE 和 REGEXP之间的重要差别
-- LIKE 匹配整个列,如果被匹配的文本在列值中出现,LIKE 将不会找到它,相应的行也不会被返回(除非使用通配符)。而 REGEXP 在列值内进行匹配,如果被匹配的文本在列值中出现,REGEXP 将会找到它,相应的行将被返回,并且 REGEXP 能匹配整个列值(与 LIKE 相同的作用)。
SQL16 查找GPA最高值
题目:运营想要知道复旦大学学生gpa最高值是多少,请你取出相应数据
select max(gpa)
from user_profile
where university = '复旦大学'
select round(max(gpa),1)
from user_profile
where university = '复旦大学'
SELECT gpa
FROM user_profile
WHERE university='复旦大学'
ORDER BY gpa DESC
LIMIT 0,1
select gpa
from(select gpa,row_number()over(partition by university order by gpa desc) as ranking
from user_profile
where university = '复旦大学') as t
where t.ranking = 1;
SELECT gpa
FROM user_profile
WHERE university ="复旦大学"
ORDER BY gpa DESC
LIMIT 1;
SQL17 计算男生人数以及平均GPA
select count(gender) as male_num,
Round(avg(gpa),1)as avg_gpa
from user_profile
where gender='male';
select
count(gender) male_num,
round(avg(gpa),1) avg_gpa
from user_profile GROUP BY gender having gender ='male'
select
count(id) male_num,avg(gpa) avg_gpa
from
user_profile
group by
gender
having
gender='male'
SQL18 分组计算练习题
现在运营想要对每个学校不同性别的用户活跃情况和发帖数量进行分析,请分别计算出每个学校每种性别的用户数、30天内平均活跃天数和平均发帖数量。
select gender,university,
count(device_id)as user_num,
avg(active_days_within_30)as avg_active_days,
avg(question_cnt)as avg_question_cnt
from user_profile
group by gender,university
select l.gender,l.university,
count(gender) as user_num ,
avg(l.active_days_within_30) as avg_active_day,
avg(l.question_cnt) as avg_question_cnt
FROM user_profile l
group by l.university ,l.gender
select gender,university,
count(gender) as user_num,
ROUND(avg(active_days_within_30),1),
ROUND(avg(question_cnt),1)
from user_profile
group by gender,universit
SQL19 分组过滤练习题
取出平均发贴数低于5的学校或平均回帖数小于20的学校
聚合函数结果作为筛选条件时,不能用where,而是用having语法
select university,
avg(question_cnt) as avg_question_cnt,
avg(answer_cnt) as avg_answer_cnt
from user_profile
group by university
having avg_question_cnt<5 or avg_answer_cnt<20
# select查询字段中有非聚合函数和聚合函数
# 一定是按照非聚合函数字段进行分组
# 按照执行顺序,是from -> where -> group by -> having -> select -> order by -> limit
# 理论上来说,select中的聚合函数字段无法在having中使用,
# 但是mysql会做自动优化的替换,无论定义在哪,聚合的操作执行一次,having里和select里都可以使用
SQL20 分组排序练习题
现在运营想要查看不同大学的用户平均发帖情况,并期望结果按照平均发帖情况进行升序排列,请你取出相应数据。
需要单独命名avg_question
select university,
avg(question_cnt) as avg_question_num
from user_profile
group by university
order by avg_question_num
不需要单独命名
select university,avg(question_cnt)
from user_profile
group by university
order by avg(question_cnt)
操作能运行成功的原因是 order by后面可以加聚合函数。但要注意,group by后面不可。
有三类后面可以加聚合函数
1、select
2、order by
3、having
由于SQL语句执行顺序如下:
FROM - ON - JOIN - WHERE
- GROUP BY - WITH - HAVING - SELECT - DISTINCT - ORDER BY - LIMIT
SQL21 浙江大学用户题目回答情况
题目:现在运营想要查看所有来自浙江大学的用户题目回答明细情况,请你取出相应数据
子查询
select device_id ,question_id,result
from question_practice_detail
where device_id=(
select device_id
from user_profile
where university="浙江大学"
);
连接查询
select q.device_id ,q.question_id,q.result
from question_practice_detail AS q,
user_profile as u
where q.device_id=u.device_id
and university="浙江大学";
内连接查询
select q.device_id ,q.question_id,q.result
from question_practice_detail AS q inner join
user_profile as u
on q.device_id=u.device_id
and university="浙江大学";
使用左外联结查询
select q.device_id,q.question_id,q.result
from question_practice_detail q
left join user_profile u
on q.device_id = u.device_id
where u.university = '浙江大学';
exists 的意思是用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
SELECT
device_id,question_id,result
FROM
question_practice_detail q
WHERE
EXISTS (SELECT
device_id
FROM
user_profile u
WHERE q.device_id = u.device_id AND university="浙江大学")
ORDER BY q.question_id
SQL22 统计每个学校的答过题的用户的平均答题数
SELECT university,
count(*)/count(DISTINCT q.device_id) avg_answer_cnt
FROM question_practice_detail q
LEFT JOIN user_profile u ON u.device_id=q.device_id
GROUP by university
select u.university,
count(u.university)/count(DISTINCT u.device_id)as answer
from
user_profile as u
inner join question_practice_detail as q
on u.device_id=q.device_id
group by u.university;
SQL24 统计每个用户的平均刷题数
运营想要查看参加了答题的山东大学的用户在不同难度下的平均答题题目数,请取出相应数据
select
t1.university,
t3.difficult_level,
count(t2.question_id)/count(distinct(t2.device_id))
as avg_answer_cnt
from
user_profile as t1,
question_practice_detail as t2,
question_detail as t3
where
t1.university ="山东大学"
and t1.device_id =t2.device_id
and t2.question_id=t3.question_id
group by
t3.difficult_level;
-- 内连接(inner join)
select
university,
difficult_level,
count(qpd.question_id) / count(DISTINCT qpd.device_id) as avg_answer_cnt
from
user_profile as u
inner join question_practice_detail as qpd on u.device_id = qpd.device_id
inner join question_detail as qd on qpd.question_id = qd.question_id
where
university = '山东大学'
group by
difficult_level
select
t.university,
t2.difficult_level,
round(
count(t1.question_id) / count(distinct t1.device_id),
4
) as avg_answer_cnt
from
user_profile t
join question_practice_detail t1 on t.device_id=t1.device_id
join question_detail t2 on t1.question_id=t2.question_id
where
t.university = '山东大学'
GROUP BY
t.university,
t2.difficult_level
ORDER BY
t.university desc
SQL25 查找山东大学或者性别为男生的信息
SELECT device_id,gender,age,gpa
from user_profile
where university='山东大学'
union all
SELECT device_id,gender,age,gpa
from user_profile
where gender='male'
不去重就得用union all,否则可以用union 或者where university = “山东大学” or gender = “male”
SQL61 检索并列出已订购产品的清单
-- 去重
select distinct prod_id from OrderItems
-- 分组
select prod_id from OrderItems group by prod_id
SQL62检索所有
# 匹配所有列
select * from Customers
# 指定列名
select cust_id, cust_name from Customers
SQL82返回 2020 年 1 月的所有订单的订单号和订单日期
select order_num,order_date
from Orders
where year(order_date)='2020' and month(order_date)= '01'
order by order_date
select *
from Orders
where order_date between '2020-01-01' and '2020-01-31'
order by order_date
select *
from Orders
where order_date like "%2020-01%"
order by order_date asc
select *
from Orders
where order_date regexp('2020-01')
order by order_date
select
order_num,
order_date
from
Orders
where
order_date < '2020-02-01 00:00:00'
and order_date >= '2020-01-01 00:00:00'
order by
order_date
SQL156 各个视频的平均完播率
问题:计算2021年里有播放记录的每个视频的完播率(结果保留三位小数),并按完播率降序排序
注:视频完播率是指完成播放次数占总播放次数的比例。简单起见,结束观看时间与开始播放时间的差>=视频时长时,视为完成播放。
-- 用avg、case when
SELECT
t.video_id ,
ROUND(
AVG(
CASE
WHEN TIMESTAMPDIFF(SECOND, t.start_time, t.end_time) >= duration THEN 1
ELSE 0
END
),
3
) AS avg_comp_play_rate
FROM
(
SELECT *
FROM
tb_user_video_log
WHERE
YEAR(end_time) = 2021
) AS t
LEFT JOIN tb_video_info t2 ON t.video_id = t2.video_id
GROUP BY
t.video_id
ORDER BY
avg_comp_play_rate desc;
select
a.video_id,
round(
sum(
case
when diff_time >= duration then 1
else 0
end
) / count(a.video_id),
3
) as avg_comp
from
(
select
*,
timestampdiff(second, start_time, end_time) as diff_time
from
tb_user_video_log
) a
left join tb_video_info b on a.video_id = b.video_id
group by
video_id
order by
avg_comp desc
SELECT
t.video_id ,
ROUND(
AVG(
CASE
WHEN TIMESTAMPDIFF(SECOND, t.start_time, t.end_time) >= duration THEN 1
ELSE 0
END
),
3
) AS avg_comp_play_rate
FROM
(
SELECT *
FROM
tb_user_video_log
WHERE
YEAR(end_time) = 2021
) t
JOIN tb_video_info t2 ON t.video_id = t2.video_id
GROUP BY
t.video_id
ORDER BY
avg_comp_play_rate desc;
SELECT
t.video_id ,
ROUND(
AVG(
CASE
WHEN TIMESTAMPDIFF(SECOND, t.start_time, t.end_time) >= duration THEN 1
ELSE 0
END
),
3
) AS avg_comp_play_rate
FROM
(
SELECT *
FROM
tb_user_video_log
WHERE
YEAR(end_time) = 2021
) t
inner JOIN tb_video_info t2 ON t.video_id = t2.video_id
GROUP BY
t.video_id
ORDER BY
avg_comp_play_rate desc;
select t1.video_id,round(ifnull(t2.c2/t1.c1,0),3) avg_comp_play_rate from
(
select video_id,count(*) c1 from tb_user_video_log
where year(start_time) = '2021' group by video_id
) t1
left join
(
select a.video_id,count(*) c2 from tb_user_video_log a
inner join tb_video_info b on a.video_id=b.video_id
where timestampdiff(second,start_time,end_time) >= b.duration and year(start_time) = '2021'
group by a.video_id
) t2
on t1.video_id = t2.video_id order by avg_comp_play_rate desc;
SQL157 平均播放进度大于60%的视频类别
计算各类视频的平均播放进度,将进度大于60%的类别输出。
-- 各类视频 的平均播放进度
select
tag,
concat(
round(
avg(
if(
timestampdiff(second, start_time, end_time) >= duration,
duration,
timestampdiff(second, start_time, end_time)
) / duration * 100
),
2
),
'%'
) as avg_play_progress
from
tb_user_video_log u
join tb_video_info v using(video_id)
group by
tag -- 筛选进度大于60%
having
replace(avg_play_progress, '%', '') > 60
order by
avg_play_progress desc;
--时间相减用timestampdiff函数
--注意时间相减直接用减号有效性差容易出错,最好用函数,如timestampdif(天(DAY)、小时(HOUR),分钟(MINUTE)和秒(SECOND),早的时间点,晚的时间点)
SELECT
CONCAT(
ROUND(
AVG(
if(
TIMESTAMPDIFF(SECOND, start_time, end_time) > duration,
1,
TIMESTAMPDIFF(SECOND, start_time, end_time) / duration
)
) * 100,
2
),
'%'
) avg_rate
FROM
tb_user_video_log a
LEFT JOIN tb_video_info b on a.video_id = b.video_id
GROUP BY
tag
HAVING
REPLACE(avg_rate, '%', '') > 60
以上是关于数据库练习题(牛客网sql入门篇部分)的主要内容,如果未能解决你的问题,请参考以下文章