记录一下最近写过的sql的一些记录,从这篇开始每天更新5个题目,sql真的非常灵活,一个题目可能有很多很多种解法,我记录的只是我自己的一个解题思路,如果大家有更好的不同解法欢迎在评论区一起探讨
ps:有些题可能解法会重复,比如求大于,我们下一个题可能是求小于,大家如果第一遍没有做出来,看了我写的之后有了思路,可以试一下反面的解法。
写sql之前先分析,需要用到的表以及函数
student,score两张表
简单分析一下这个sql,因为01课程和02课程在同一个字段,所以我的思路是采用自连接来处理
SELECT
c.*,
a.s_score score1,
b.s_score score2
FROM
score a,
score b,
student c
WHERE
a.c_id = '1'
AND b.c_id = '2'
AND a.s_id = b.s_id
AND c.s_id = b.s_id
AND a.s_score > b.s_score;
结果如下:
同样的思路,再写一遍,巩固一下
SELECT
c.*,
a.s_score score1,
b.s_score score2
FROM
score a,
score b,
student c
WHERE
a.c_id = '1'
AND b.c_id = '2'
AND a.s_id = b.s_id
AND c.s_id = b.s_id
AND a.s_score < b.s_score;
需要用的表为student,score
题目需要查询到学生姓名,需要利用子查询
函数为age求平均值函数
需要分组
SELECT
b.s_id,
(
SELECT
s.s_name
FROM
student s
WHERE
b.s_id = s.s_id
) s_name,
AVG(b.s_score) avg_score
FROM
score b
GROUP BY
b.s_id
HAVING
AVG(b.s_score) >= 60
思路和上面一模一样
SELECT
a.s_id,
(
SELECT
s.s_name
FROM
student s
WHERE
a.s_id = s.s_id
),
avg(a.s_score)
FROM
score a
GROUP BY
a.s_id
HAVING
avg(a.s_score) <= 60;
从题目的意思可以看出来,我们需要两个表student,score
用到的函数为,count,sum
和上一个题的思路其实很像
ps:我个人比较喜欢子查询的方式,其实很多人比较喜欢用内连接,其实没有啥本质上区别,看个人习惯吧
子查询:
SELECT
s.s_id,
(
SELECT
a.s_name
FROM
student a
WHERE
a.s_id=s.s_id
),
COUNT(s.c_id),
SUM(s.s_score)
FROM
score s
GROUP BY
s.s_id;
显式内连接:
SELECT
a.s_id,
s.s_name,
COUNT(a.c_id),
SUM(a.s_score)
FROM
score a
INNER JOIN student s ON s.s_id = a.s_id
GROUP BY
a.s_id;
不知道有没有细心的小伙伴发现,我们这张成绩表中缺少id为8的同学的成绩,可能因为某些情况缺考了导致我们在上面的查询中也查不到她的信息,那么如果我们也需要将他的信息查询出来应该如何做呢?
student中有的数据而score中没有,可以使用外连接来做
SELECT
s.s_id,
s.s_name,
COUNT(a.c_id) count_cid,
IFNULL(SUM(a.s_score), 0) sum_score
FROM
score a
RIGHT JOIN student s ON s.s_id = a.s_id
GROUP BY
a.s_id
ORDER BY
s_id ASC;