面试题,有三张表,学生表S,课程表C,学生课程表SC,学生可以选修多门课程,一门课程可能被多个学生选修,通过SC表关联。
(1)写出建表以及插入语句;
(2)写出SQL语句,查询选修了所有选修课程的学生;
(3)写出SQL语句,查询选修了至少2门课程的学生;
#(1)
create table S(
s_id int primary key auto_increment,
s_name varchar(20) not null
);
create table C(
c_id int primary key auto_increment,
c_name varchar(20) not null
);
create table SC(
s_id int references S(s_id),
c_id int references C(c_id)
);
INSERT INTO S VALUES (1,'zhangsan'),(2,'lsii'),(3,'wangwu'),(4,'zhaoliu');
INSERT INTO C VALUES(1,'Java'),(2,'C++'),(3,'Chinese'),(4,'English');
INSERT INTO SC VALUES(1,1),(1,2),(1,3),(1,4),(2,1),(2,2),(2,3),(3,1),(3,2),(4,3),(4,4);
#(2)
SELECT * FROM S
WHERE s_id IN(
SELECT s_id FROM SC
GROUP BY s_id HAVING COUNT(*)=(SELECT COUNT(*) FROM C)
);
#第二种写法
首先头脑中有三点概念:
1. EXISTS 子查询找到的提交
NOT EXISTS 子查询中 找不到的提交
说明:不要去翻译为存在和不存在,把脑袋搞晕。
2. 建立程序循环的概念,这是一个动态的查询过程。如 FOR循环 。
3. Exists执行的流程Exists首先执行外层查询,再执行内存查询,与IN相反。流程为首先取出外层中的第一元组,再执行内层查询,将外层表的第一元组代入,若内层查询为真,即有结果时。返回外层表中的第一元 组,接着取出第二元组,执行相同的算法。一直到扫描完外层整表 。
select * from S
where NOT exists
(select * from C
where NOT exists --不存在的提交给course
(select * from SC where
s_id = S.s_id and c_id = C.c_id)) --代入两个未知变量
#(3)
select * from S
where s_id in (
select s_id from SC
group by s_id having count(*) >= 2
);