表結構
- 學生表student(id,name)
- 課程表course(id,name)
- 學生課程表student_course(sid,cid,score)
創建表的sql代碼
```sql
create table student(
id int unsigned primary key auto_increment,
name char(10) not null
);
insert into student(name) values('張三'),('李四');
create table course(
id int unsigned primary key auto_increment,
name char(20) not null
);
insert into course(name) values('語文'),('數學');
create table student_course(
sid int unsigned,
cid int unsigned,
score int unsigned not null,
foreign key (sid) references student(id),
foreign key (cid) references course(id),
primary key(sid, cid)
);
insert into student_course values(1,1,80),(1,2,90),(2,1,90),(2,2,70);
```
問題
-
查詢student表中重名的學生,結果包含id和name,按name,id升序
select id,name from student where name in ( select name from student group by name having(count(*) > 1) ) order by name;
-
在student_course表中查詢平均分不及格的學生,列出學生id和平均分
select sid,avg(score) as avg_score from student_course group by sid having(avg_score<60);
-
在student_course表中查詢每門課成績都不低於80的學生id
select distinct sid from student_course where sid not in ( select sid from student_course where score < 80);
∀x:P和¬∃x:¬P
是等價的。 -
查詢每個學生的總成績,結果列出學生姓名和總成績 如果使用下面的sql會過濾掉沒有成績的人
select name,sum(score) total from student,student_course where student.id=student_course.sid group by sid;
select name,sum(score) from student left join student_course on student.id=student_course.sid group by sid;
-
總成績最高的學生,結果列出學生id和總成績 下面的sql效率很低,因為要重復計算所有的總成績。
select sid,sum(score) as sum_score from student_course group by sid having sum_score>=all (select sum(score) from student_course group by sid);
select sid,sum(score) as sum_score from student_course group by sid order by sum_score desc limit 1;
-
在student_course表查詢課程1成績第2高的學生,如果第2高的不止一個則列出所有的學生
這是個查詢 第N大數 的問題。 我們先查出第2高的成績:
select min(score) from student_course where cid = 1 group by score order by score desc limit 2;
group by->min->order by->limit
,mysql提供了limit offset,size這種方式來取第N大的值,因此正確的做法是:select score from student_course where cid = 1 group by score order by score desc limit 1,1;
select * from student_course where cid=1 and score = ( select score from student_course where cid = 1 group by score order by score desc limit 1,1 );
-
在student_course表查詢各科成績最高的學生,結果列出學生id、課程id和對應的成績 你可能會這樣寫:
select sid,cid,max(score) from student_course group by cid;
select * from student_course as x where score>= (select max(score) from student_course as y where cid=x.cid);
- 子查詢一定要有括號
- as可以省略
- 使用相關查詢;>=max等價於>=all,但是聚合函數比使用any或all效率高
-
在student_course表中查詢每門課的前2名,結果按課程id升序,同一課程按成績降序 這個問題也就是取每組的前N條紀錄,類似的查詢在csdn上也有征集答案
select * from student_course x where 2>(select count(*) from student_course y where y.cid=x.cid and y.score>x.score) order by cid,score desc;
-
一個叫team的表,里面只有一個字段name,一共有4條紀錄,分別是a,b,c,d,對應四個球隊,兩兩進行比賽,用一條sql語句顯示所有可能的比賽組合
select a.name, b.name from team a, team b where a.name < b.name
-
題目:數據庫中有一張如下所示的表,表名為sales。
年 季度 銷售 1991 1 11 1991 2 12 1991 3 13 1991 4 14 1992 1 21 1992 2 22 1992 3 23 1992 4 24 要求:寫一個SQL語句查詢出如下所示的結果。
年 一季度 二季度 三季度 四季度 1991 11 12 13 14 1992 21 22 23 24 select 年, sum(case when 季度=1 then 銷售量 else 0 end) as 一季度, sum(case when 季度=2 then 銷售量 else 0 end) as 二季度, sum(case when 季度=3 then 銷售量 else 0 end) as 三季度, sum(case when 季度=4 then 銷售量 else 0 end) as 四季度 from sales group by 年;
create view temp as select student.name as sname,course.name as cname,score from student_course join (student,course) on(student_course.sid=student.id and student_course.cid=course.id) ; select sname, sum(case when cname='語文' then score else 0 end) as 語文, sum(case when cname='數學' then score else 0 end) as 數學 from temp group by sname;