多表內容的增刪改查


笛卡爾積

將兩表所有的數據一一對應,生成一張大表 不建議

select * from dep,emp;  #兩個表拼一起
select * from dep,emp where dep.id = emp.dep_id; #找到兩表之間對應的關系記錄
select * from dep,emp where dep.id = emp.dep_id and dep.name='技術'; #篩選部門名稱為技術的大表中的記錄
select emp.name from dep,emp where dep.id = emp.dep_id and dep.name='技術'; #拿到篩選后的記錄的員工姓名字段數據

連表查詢

inner join 內連接

select * from 表名 inner join 表2 on dep.id=emp.dep_id;
第一步:連表
    select * from dep inner join emp on dep.id=emp.dep_id;
第二步: 過濾
    select * from dep inner join emp on dep.id=emp.dep_id where dep.name='技術';
第三步:找對應字段數據
    select emp.name from dep inner join emp on dep.id=emp.dep_id where dep.name='技術';

left join 左連接

(left join左邊的表為主表,主表記錄必須全部顯示,輔表沒辦法對應上的,就通過null來補全)

select * from dep left join emp on dep.id=emp.dep_id;

right join 右連接

select * from dep right join emp on dep.id=emp.dep_id;

union 全連接

mysql> select * from dep left join emp on dep.id=emp.dep_id
    -> union
    -> select * from dep right join emp on dep.id=emp.dep_id;

子查詢

(一個查詢結果集作為另一個查詢的條件)

select name from emp where dep_id = (select id from dep where name = '技術');

左連接 ,右連接,內連接和全外連接的4者區別

基本定義:
  left join (左連接):返回包括左表中的所有記錄和右表中連接字段相等的記錄。
  right join (右連接):返回包括右表中的所有記錄和左表中連接字段相等的記錄。
  inner join (等值連接或者叫內連接):只返回兩個表中連接字段相等的行。
  full join (全外連接):返回左右表中所有的記錄和左右表中連接字段相等的記錄。

小練習1

書名  作者  出版社 價格  出版日期
倚天屠龍記   egon    北京工業地雷出版社   70  2019-7-1
九陽神功    alex    人民音樂不好聽出版社  5   2018-7-4
九陰真經    yuan    北京工業地雷出版社   62  2017-7-12
九陰白骨爪   jinxin  人民音樂不好聽出版社  40  2019–8-7
獨孤九劍    alex    北京工業地雷出版社   12  2017-9-1
降龍十巴掌   egon    知識產權沒有用出版社  20  2019-7-5
葵花寶典    yuan    知識產權沒有用出版社  33  2019–8-2
0.建表book,並向表中插入數據
create table book(
    書名 varchar(12),
    作者 varchar(12),
    出版社 varchar(12),
    價格 int unsigned not null,
    出版日期 date
);
insert into book values
('倚天屠龍記','egon','北京工業地雷出版社',70,'2019-7-1'),
('九陽神功','alex','人民音樂不好聽出版社',5,'2018-7-4'),
('九陰真經','yuan','北京工業地雷出版社',62,'2017-7-12'),
('九陰白骨爪','jinxin','人民音樂不好聽出版社',40,'2019–8-7'),
('獨孤九劍','alex','北京工業地雷出版社',12,'2017-9-1'),
('降龍十巴掌','egon','知識產權沒有用出版社',20,'2019-7-5'),
('葵花寶典','yuan','知識產權沒有用出版社',33,'2019–8-2');

1.查詢 egon 寫的所有書和價格
select 書名,價格 from book where 作者='egon';
2.找出最貴的圖書的價格
select 書名,價格 from book ;
3.求所有圖書的均價
4.將所有圖書按照出版日期排序
5.查詢alex寫的所有書的平均價格
6.查詢人民音樂不好聽出版社出版的所有圖書
7.查詢人民音樂出版社出版的alex寫的所有圖書和價格
8.找出出版圖書均價最高的作者
9.找出最新出版的圖書的作者和出版社
10.顯示各出版社出版的所有圖書
11.查找價格最高的圖書,並將它的價格修改為50元
12.刪除價格最低的那本書對應的數據
13.將所有alex寫的書作業修改成alexsb
14.select year(publish_date) from book
自己研究上面sql語句中的year函數的功能,完成需求:
將所有2017年出版的圖書從數據庫中刪除
15.有文件如下,使用python寫代碼將文件中的數據寫入數據庫
學python從開始到放棄|alex|人民大學出版社|50|2018-7-1
學mysql從開始到放棄|egon|機械工業出版社|60|2018-6-3
學html從開始到放棄|alex|機械工業出版社|20|2018-4-1
學css從開始到放棄|wusir|機械工業出版社|120|2018-5-2
學js從開始到放棄|wusir|機械工業出版社|100|2018-7-30

答案
#第一步手動創建表
# create table book(
#     id int primary key auto_increment,
#     book_name char(20) not null,
#     author char(12) not null,
#     press char(20) not null,
#     price float(6,2),
#     pub_date date
# );

# 寫入數據
import pymysql
conn = pymysql.Connection(host='127.0.0.1', user='root', password="",
                 database='daycs')
cur = conn.cursor()#右邊
with open('book.txt',encoding='utf-8') as f:
    try:
        for line in f:
            line = line.strip()
            if '\t' in line:
                lst = line.split('\t')
            elif '|' in line:
                lst = line.split('|')
            sql = 'insert into book(book_name,author,press,price,pub_date) values (%s,%s,%s,%s,%s);'
            cur.execute(sql,lst)
    except Exception:
        conn.rollback()#操作不成功 回滾
conn.commit()
cur.close()
conn.close()

# select book_name,price from book where author = 'egon'

# 2.找出最貴的圖書的價格
# select max(price) from book;
# select price,book_name from book order by price desc limit 1;

# 3.求所有圖書的均價
# select avg(price) from book;

# 4.將所有圖書按照出版日期排序
# select * from book order by pub_date;

# 5.查詢alex寫的所有書的平均價格
# select avg(price) from book where author = 'alex'

# 擴展: 求所有人自己出版的圖書的平均價格
# select author,avg(price) from book group by author
# 擴展: 求所有人自己出版的圖書的平均價格>30的所有人
# select author from book group by author having  avg(price)>30

# 6.查詢人民音樂不好聽出版社出版的所有圖書
# select * from book where press = '人民音樂不好聽出版社';

# 7.查詢人民音樂出版社出版的alex寫的所有圖書和價格
# select * from book where press = '人民音樂不好聽出版社' and author = 'alex';

# 8.找出出版圖書均價最高的作者
# select author,avg(price) as avg_p from book group by author order by avg_p desc limit 1;

# 9.找出最新出版的圖書的作者和出版社
# select author,press from book order by pub_date desc limit 1;

# 10.顯示各出版社出版的所有圖書
# select press,group_concat(book_name) from book group by press;

# 11.查找價格最高的圖書,並將它的價格修改為50元
# select max(price) from book;
# update book set price = 50 where price = 70

# 12.刪除價格最低的那本書對應的數據
# select min(price) from book;
# delete from book where price = 5;

# 13.將所有alex寫的書作者修改成alexsb
# update book set author = 'alexsb' where author = 'alex';

# 14.select year(publish_date) from book
# 自己研究上面sql語句中的year函數的功能,完成需求:
# 將所有2017年出版的圖書從數據庫中刪除
# delete from book where year(publish_date) = 2017;

小練習2

鍵表准備

數據導入

init.sql文件內容
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50624
 Source Host           : localhost
 Source Database       : sqlexam

 Target Server Type    : MySQL
 Target Server Version : 50624
 File Encoding         : utf-8

 Date: 10/21/2016 06:46:46 AM
*/

SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
--  Table structure for `class`
-- ----------------------------
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `caption` varchar(32) NOT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `class`
-- ----------------------------
BEGIN;
INSERT INTO `class` VALUES ('1', '三年二班'), ('2', '三年三班'), ('3', '一年二班'), ('4', '二年九班');
COMMIT;

-- ----------------------------
--  Table structure for `course`
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `cname` varchar(32) NOT NULL,
  `teacher_id` int(11) NOT NULL,
  PRIMARY KEY (`cid`),
  KEY `fk_course_teacher` (`teacher_id`),
  CONSTRAINT `fk_course_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `course`
-- ----------------------------
BEGIN;
INSERT INTO `course` VALUES ('1', '生物', '1'), ('2', '物理', '2'), ('3', '體育', '3'), ('4', '美術', '2');
COMMIT;

-- ----------------------------
--  Table structure for `score`
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `student_id` int(11) NOT NULL,
  `course_id` int(11) NOT NULL,
  `num` int(11) NOT NULL,
  PRIMARY KEY (`sid`),
  KEY `fk_score_student` (`student_id`),
  KEY `fk_score_course` (`course_id`),
  CONSTRAINT `fk_score_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`cid`),
  CONSTRAINT `fk_score_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `score`
-- ----------------------------
BEGIN;
INSERT INTO `score` VALUES ('1', '1', '1', '10'), ('2', '1', '2', '9'), ('5', '1', '4', '66'), ('6', '2', '1', '8'), ('8', '2', '3', '68'), ('9', '2', '4', '99'), ('10', '3', '1', '77'), ('11', '3', '2', '66'), ('12', '3', '3', '87'), ('13', '3', '4', '99'), ('14', '4', '1', '79'), ('15', '4', '2', '11'), ('16', '4', '3', '67'), ('17', '4', '4', '100'), ('18', '5', '1', '79'), ('19', '5', '2', '11'), ('20', '5', '3', '67'), ('21', '5', '4', '100'), ('22', '6', '1', '9'), ('23', '6', '2', '100'), ('24', '6', '3', '67'), ('25', '6', '4', '100'), ('26', '7', '1', '9'), ('27', '7', '2', '100'), ('28', '7', '3', '67'), ('29', '7', '4', '88'), ('30', '8', '1', '9'), ('31', '8', '2', '100'), ('32', '8', '3', '67'), ('33', '8', '4', '88'), ('34', '9', '1', '91'), ('35', '9', '2', '88'), ('36', '9', '3', '67'), ('37', '9', '4', '22'), ('38', '10', '1', '90'), ('39', '10', '2', '77'), ('40', '10', '3', '43'), ('41', '10', '4', '87'), ('42', '11', '1', '90'), ('43', '11', '2', '77'), ('44', '11', '3', '43'), ('45', '11', '4', '87'), ('46', '12', '1', '90'), ('47', '12', '2', '77'), ('48', '12', '3', '43'), ('49', '12', '4', '87'), ('52', '13', '3', '87');
COMMIT;

-- ----------------------------
--  Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `gender` char(1) NOT NULL,
  `class_id` int(11) NOT NULL,
  `sname` varchar(32) NOT NULL,
  PRIMARY KEY (`sid`),
  KEY `fk_class` (`class_id`),
  CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `student`
-- ----------------------------
BEGIN;
INSERT INTO `student` VALUES ('1', '男', '1', '理解'), ('2', '女', '1', '鋼蛋'), ('3', '男', '1', '張三'), ('4', '男', '1', '張一'), ('5', '女', '1', '張二'), ('6', '男', '1', '張四'), ('7', '女', '2', '鐵錘'), ('8', '男', '2', '李三'), ('9', '男', '2', '李一'), ('10', '女', '2', '李二'), ('11', '男', '2', '李四'), ('12', '女', '3', '如花'), ('13', '男', '3', '劉三'), ('14', '男', '3', '劉一'), ('15', '女', '3', '劉二'), ('16', '男', '3', '劉四');
COMMIT;

-- ----------------------------
--  Table structure for `teacher`
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `tid` int(11) NOT NULL AUTO_INCREMENT,
  `tname` varchar(32) NOT NULL,
  PRIMARY KEY (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `teacher`
-- ----------------------------
BEGIN;
INSERT INTO `teacher` VALUES ('1', '張磊老師'), ('2', '李平老師'), ('3', '劉海燕老師'), ('4', '朱雲海老師'), ('5', '李傑老師');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

准備表、記錄

mysql> create database db1;
mysql> use db1;
mysql> source /root/init.sql

查表

select * from class;#班級
+-----+--------------+
| cid | caption      |
+-----+--------------+
|   1 | 三年二班     |
+-----+--------------+
select * from course;#課程
+-----+--------+------------+
| cid | cname  | teacher_id |
+-----+--------+------------+
|   1 | 生物   |          1 |
+-----+--------+------------+
mysql> select * from score;#分數
+-----+------------+-----------+-----+
| sid | student_id | course_id | num |
+-----+------------+-----------+-----+
|   1 |          1 |         1 |  10 |
+-----+------------+-----------+-----+
mysql> select * from student;#學生
+-----+--------+----------+--------+
| sid | gender | class_id | sname  |
+-----+--------+----------+--------+
|   1 | 男     |        1 | 理解   |
+-----+--------+----------+--------+
mysql> select * from teacher;#老師
+-----+-----------------+
| tid | tname           |
+-----+-----------------+
|   1 | 張磊老師        |
+-----+-----------------+

1、查詢男生、女生的人數;

select count(gender) from student group by gender;

2、查詢姓“張”的學生名單;

select * from student where sname like '張%';

3、課程平均分從高到低顯示

select avg(num) from  score group by  course_id order by avg(num) desc;

4、查詢有課程成績小於60分的同學的學號、姓名;

1查詢小於60的的學生id
select student_id from score where num<60;
2利用學生id在學生表查姓名
select sid,sname from student where sid in (select student_id from score where num<60);

5、查詢至少有一門課與學號為1的同學所學課程相同的同學的學號和姓名;

1先查出學號1的所學課程
select course_id from score where student_id=1;
2查分數表 只要符合 學的課程在1號同學就行 獲取學生id
select student_id from score where course_id in (select course_id from score where student_id=1) and student_id !=1 group by student_id;
3學生id獲取姓名
select sid,sname from student where sid in (select student_id from score where course_id in (select course_id from score where student_id=1) and student_id !=1 group by student_id);

6、查詢出只選修了一門課程的全部學生的學號和姓名;

1先查學生id
select student_id from score group by student_id order by count(course_id)=1;
2id查姓名
select sid,sname from student where sid in (select student_id from score group by student_id order by count(course_id)=1);

7、查詢各科成績最高和最低的分:以如下形式顯示:課程ID,最高分,最低分;

select course_id,max(num),min(num) from score group by course_id;

8、查詢課程編號“2”的成績比課程編號“1”課程低的所有同學的學號、姓名;

1先查出課程編號1的學生信息
select * from score where course_id=1;
2查出課程編號2的學生信息
select * from score where course_id=2;
3連表查詢 左外連接 利用學生id相同 找出學生id
select t1.student_id from (select * from score where course_id=1) t2 inner join (select * from score where course_id=2) t1 on t1.student_id = t2.student_id where t1.num<t2.num;
4學生id 找姓名
select sid,sname from student where sid in (select t1.student_id from (select * from score where course_id=1) t2 inner join (select * from score where course_id=2) t1 on t1.student_id = t2.student_id where t1.num<t2.num);

9、查詢“生物”課程比“物理”課程成績高的所有學生的學號;

1先查生物id
select cid from course where cname='生物';
2查物流id
select cid from course where cname='物理';
3利用id 查生物成績
select * from score where course_id =(select cid from course where cname='生物');
3利用id 查物理成績
select * from score where course_id =(select cid from course where cname='物理');
4連表 找出學生id
select t1.student_id from (select * from score where course_id =(select cid from course where cname='生物')) t2 inner join (select * from score where course_id =(select cid from course where cname='物理')) t1 on t1.student_id = t2.student_id where t1.num>t2.num ;
5 id找姓名
select sid,sname from student where sid in (select t1.student_id from (select * from score where course_id =(select cid from course where cname='生物')) t2 inner join (select * from score where course_id =(select cid from course where cname='物理')) t1 on t1.student_id = t2.student_id where t1.num<t2.num);

10、查詢平均成績大於60分的同學的學號和平均成績;

1學生分組
select student_id,avg(num) from score group by student_id order by avg(num) >60;

11、查詢所有同學的學號、姓名、選課數、總成績;

1學生分組
select student_id,avg(num),count(course_id) from score group by student_id;
2連表
select t1.student_id,t1.pjnum,t1.zcourse,t2.sname from (select student_id,avg(num) as pjnum,count(course_id) as zcourse from score group by student_id) as t1 inner join (select * from student) t2 on t1.student_id=t2.sid;

12、查詢姓“李”的老師的個數;

1先查姓李的老師id 在計數
select count(tid) from teacher where tname like '李%';

13、查詢沒學過“張磊老師”課的同學的學號、姓名;

1找到張磊老師id
select tid from teacher where tname='張磊老師';
2查詢張磊老師教什么課
select cid from course where teacher_id=(select tid from teacher where tname='張磊老師');
3找學過的
select student_id from score where course_id in (select cid from course where teacher_id=(select tid from teacher where tname='張磊老師'));
4逆向思維
select sid,sname from student where sid not in (select student_id from score where course_id in (select cid from course where teacher_id=(select tid from teacher where tname='張磊老師')));

14、查詢學過“1”並且也學過編號“2”課程的同學的學號、姓名;

1查詢學過編號1的
select student_id from score where course_id=1;
2查詢學過編號2的
select student_id from score where course_id=2;
3連表 找id
select t1.student_id from (select student_id from score where course_id=1) as t1 inner join (select student_id from score where course_id=2) as t2 on t1.student_id=t2.student_id;
4id找名字
select sid,sname from student where sid in (select t1.student_id from (select student_id from score where course_id=1) as t1 inner join (select student_id from score where course_id=2) as t2 on t1.student_id=t2.student_id);

15、查詢學過“李平老師”所教的所有課的同學的學號、姓名;

select student_id from score where course_id in (select cid from course where teacher_id=(select tid from teacher where tname='張磊老師'));
id 找名字
select sid,sname from student where sid in (select student_id from score where course_id in (select cid from course where teacher_id=(select tid from teacher where tname='張磊老師')));

1、查詢沒有學全所有課的同學的學號、姓名;

1總課程數
select count(cid) from course;
2分組 找id
select student_id from score group by student_id having count(course_id)=(select count(cid) from course);
id 找名字
select sid,sname from student where sid in (select student_id from score group by student_id having count(course_id)=(select count(cid) from course));

刪除學習“李平”老師課的SC(score)表記錄;

# 先查出李平老師的id
select tid from teacher where tname = '李平老師';
# 查看李平老師所教授的課程
select cid from course where teacher_id = (select tid from teacher where tname = '李平老師’);
# 查看李平老師所教課程的成績數據
select * from score where course_id in (select cid from course where teacher_id = (select tid from teacher where tname = '李平老師'));
# 執行刪除命令
delete from score where course_id in (select cid from course where teacher_id = (select tid from teacher where tname = '李平老師'));
# 先查詢2號同學學了哪些課程
select * from score where student_id =2;
# 找到學習了2號同學沒學習課程的所有同學(找到所有和2號同學學習的課程不一樣的同學)
select student_id from score where course_id not in (select course_id from score where student_id=2)
# 找到score表中所有的學生並且把 2號同學 以及(和2號同學學習的課程不一樣的同學)排除出去
select student_id from score where student_id not in (select student_id from score where course_id not in (select course_id from score where student_id=2)) and student_id !=2
# 對剩余的和2號同學所選課程沒有不同的同學所選課程數進行統計,如果和2號同學的課程數相同,就是選擇了相同的課程
select student_id from score where student_id not in (
 select student_id from score where course_id not in (select course_id from score where student_id=2)
 ) and student_id !=2
group by student_id 
having count(course_id)= (select count(course_id) from score where student_id=2);

6、查詢各科成績最高和最低的分:以如下形式顯示:課程ID,最高分,最低分;

select course_id 課程ID,max(num) 最高分,min(num) 最低分 from score group by course_id;

7、按各科平均成績從低到高和及格率的百分數從高到低順序;

# 方法1:
# 先求平均成績
select course_id,avg(num) from score group by course_id;
# 解決計算各科及格率的問題
所有及格的人/所有人數
select t1.course_id,t1.count1/t2.count2 from 
(select course_id,count(course_id) count1 from score where num>60 group by course_id) t1 
left join

(select course_id,count(course_id) count2 from score group by course_id) t2

on t1.course_id = t2.course_id;

# 根據上述內容進行表的拼接

select  t_out1.course_id,t_out1.avgnum, t_out2.pass_per from 

(select course_id,avg(num) avgnum from score group by course_id ) t_out1

left join 

(select t1.course_id,t1.count1/t2.count2 pass_per from 

(select course_id,count(course_id) count1 from score where num>60 group by course_id) t1 
left join
(select course_id,count(course_id) count2 from score group by course_id) t2
on t1.course_id = t2.course_id) t_out2
on  t_out1.course_id = t_out2.course_id
# 加上排序
select  t_out1.course_id,t_out1.avgnum, t_out2.pass_per from  (select course_id,avg(num) avgnum from score group by course_id ) t_out1 left join  (select t1.course_id,t1.count1/t2.count2 pass_per from  (select course_id,count(course_id) count1 from score where num>60 group by course_id) t1  left join (select course_id,count(course_id) count2 from score group by course_id) t2 on t1.course_id = t2.course_id) t_out2 on  t_out1.course_id = t_out2.course_id order by avgnum ,pass_per desc;

# 方法2 
# 使用case when直接計算合格率
select 
sum(case when num>60 then 1 else 0 end)/count(course_id)
from score group by course_id
# 加上課程id和平均值
select  course_id,avg(num),
sum(case when num>60 then 1 else 0 end)/count(course_id)
from score group by course_id
# 加上排序
select  course_id,avg(num) avgnum,
sum(case when num>60 then 1 else 0 end)/count(course_id) pass_per 
from score group by course_id
order by avgnum ,pass_per desc;

9、查詢每門課程被選修的學生數;

select course_id,count(course_id) from score group by course_id;

10、查詢同名同姓學生名單,並統計同名人數;

select sname,count(1) as count from student group by sname;

11、查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列;

select course_id,avg(if(isnull(num), 0 ,num)) as avg from score group by course_id order by avg  asc,course_id desc;

12、查詢平均成績大於85的所有學生的學號、姓名和平均成績;

select student_id,sname, avg(if(isnull(num), 0 ,num)) from score left join student on score.student_id = student.sid group by student_id;

13、查詢課程名稱為“數學”,且分數低於60的學生姓名和分數;

select student.sname,score.num from score
left join course on score.course_id = course.cid
left join student on score.student_id = student.sid
where score.num < 60 and course.cname = '數學'
14、查詢課程編號為003且課程成績在80分以上的學生的學號和姓名; 
select * from score where score.student_id = 3 and score.num > 80

15、求選了課程的學生人數

select sid,sname from student where sid not in (select student_id from score group by student_id);

16、查詢選修“楊艷”老師所授課程的學生中,成績最高的學生姓名及其成績;

# 先找到“楊艷”老師的教師id
select tid from teacher where tname = '楊艷';
# 再找到楊艷老師教的所有課程
select cid from course where teacher_id in (select tid from teacher where tname = '楊艷');
# 再找到楊艷老師教的所有課程的最高分
select max(num) from score where course_id in (select cid from course where teacher_id in (select tid from teacher where tname = '李平老師'));
# 再找到楊艷老師教的所有課程的最高分對應的學生
select distinct student_id,num from score 
where num = (select max(num) from score where course_id in (select cid from course where teacher_id in (select tid from teacher where tname = '李平老師'))) 
and course_id in   (select cid from course where teacher_id in (select tid from teacher where tname = '李平老師'));
# 找到學生的姓名
select student.sname,t1.num from(
select distinct student_id,num from score 
where num = (select max(num) from score where course_id in (select cid from course where teacher_id in (select tid from teacher where tname = '李平老師'))) 
and course_id in   (select cid from course where teacher_id in (select tid from teacher where tname = '李平老師'))
) t1
left join
student
on 
t1.student_id = student.sid;

17、查詢各個課程及相應的選修人數;

select course.cname,count(1) from score
left join course on score.course_id = course.cid
group by course_id;

查詢不同課程但成績相同的學生的學號、課程號、學生成績;

select DISTINCT s1.course_id,s2.course_id,s1.num,s2.num from score as s1, score as s2 where s1.num = s2.num and s1.course_id != s2.course_id;

9、查詢每門課程成績最好的前兩名;

   先查詢每條數據對應學科成績的第一名和第二名,這里必須要保留所有的s1,以便后續進行連表查詢

select sid,course_id,
    (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0, 1) as first_num,
    (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 1, 1) as second_num
from score as s1

按照sid連表,把學生的成績和對應的第一名、第二名成績連起來
select
* from score t1
left join
    (
    select sid,course_id,
    (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0, 1) as first_num,
    (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 1, 1) as second_num
    from score as s1
    ) t2
on t1.sid = t2.sid

判斷如果學生的成績是第一名、第二名的成績,那么就符合條件,顯示學生的id、學科和成績
select
t1.sid,t1.student_id,t1.course_id,t1.num from score t1
left join
    (
    select sid,course_id,
    (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0, 1) as first_num,
    (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 1, 1) as second_num
    from score as s1
    ) t2
on t1.sid = t2.sid
where t1.num = t2.first_num or t1.num = t2.second_num;

20、檢索至少選修兩門課程的學生學號;

select student_id from score group by student_id having count(student_id) > 1;

21、查詢全部學生都選修的課程的課程號和課程名;

# 先查看一共有多少學生
select count(sid) from student;
#  查看哪一門課選秀的學生個數和學生的總個數相等
select course_id from score group by course_id having count(student_id) = (select count(sid) from student);

2、查詢沒學過“葉平”老師講授的任一門課程的學生姓名;

# 先查看要查找老師的id
select tid from teacher where tname = '李平老師';
# 查看該老師交了哪些課程
select cid from course where teacher_id in (select tid from teacher where tname = '李平老師')
# 看看有多少學生學習了該老師的課程
select distinct student_id from score where course_id in (select cid from course where teacher_id in (select tid from teacher where tname = '李平老師'));
# 把不在上表中的學生姓名查出來
select sname from student where sid not in (select distinct student_id from score where course_id in (select cid from course where teacher_id in (select tid from teacher where tname = '李平老師')));

23、查詢兩門以上不及格課程的同學的學號及其平均成績;

select student_id,avg(num) from score where num<60 group by student_id having count(num)>=2;

24、檢索“004”課程分數小於60,按分數降序排列的同學學號;

select student_id from score where num< 60 and course_id = 4 order by num desc;

25、刪除“002”同學的“001”課程的成績;

delete from score where course_id = 1 and student_id = 2

5、按平均成績從低到高顯示所有學生的“語文”、“數學”、“英語”三門的課程成績,按如下形式顯示: 學生ID,語文,數學,英語,有效課程數,有效平均分;

# 查看每個學生的數學成績
select student_id,num from score where course_id = (select cid from course where cname = '數學');
#  查看每個學生的語文成績
select student_id,num from score where course_id = (select cid from course where cname = '語文');
#  查看每個學生的英語成績
select student_id,num from score where course_id = (select cid from course where cname = '英語');
# 查看每個學生的平均成績
select student_id,avg(num),count(num) from score group by student_id;
# 將上面的幾張表拼接起來,為了生成所有學生的信息,用student表作為左連接的第一張表
select sid 學生ID,t2.num 語文,t1.num 數學, t3.num 英語,t4.count_course 有效課程數,t4.avg_num 有效平均分 from student 
 left join (select student_id,num from score where course_id = (select cid from course where cname = '數學')) t1
 on student.sid = t1.student_id
 left join (select student_id,num from score where course_id = (select cid from course where cname = '語文')) t2
 on student.sid = t2.student_id
 left join (select student_id,num from score where course_id = (select cid from course where cname = '英語')) t3
 on student.sid = t3.student_id
 left join (select student_id,avg(num) avg_num,count(num) count_course from score group by student_id)  t4
 on student.sid = t4.student_id

4、向SC表中插入一些記錄,這些記錄要求符合以下條件:①沒有上過編號“002”課程的同學學號;②插入“002”號課程的平均成績

#  先找尋上過2號課程的同學
select student_id from score where course_id = 2;
# 再找到沒上過2號課程的所有同學
select * from student where sid not in (select student_id from score where course_id = 2);
#計算出學習2號課程的同學的平均成績
select avg(num) from score where course_id = 2 group by course_id;
# 用笛卡爾積將上述兩個表拼起來
select * from (select sid from student where sid not in (select student_id from score where course_id = 2)) t1,(select avg(num) from score where course_id = 2 group by course_id) t2;
#  向SC表中插入記錄
insert into score (course_id,student_id,num)   select 2,t1.sid,t2.avg_num from (select sid from student where sid not in (select student_id from score where course_id = 2)) t1,(select avg(num) avg_num from score where course_id = 2 group by course_id) t2;

8、查詢各科成績前三名的記錄:(不考慮成績並列情況)

select
t1.sid,t1.student_id,t1.course_id,t1.num from score t1
left join
    (
    select sid,course_id,
    (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0, 1) as first_num,
    (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 1, 1) as second_num,
    (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 2, 1) as third_num
    from score as s1
    ) t2
on t1.sid = t2.sid
where t1.num = t2.first_num or t1.num = t2.second_num or t1.num = t2.third_num;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM