mysql联表查询多记录显示_数据库:MySQL(多表的表记录的查询)(三)
一、外鍵約束
1、創(chuàng)建外鍵
---每一個(gè)班主任會(huì)對(duì)應(yīng)多個(gè)學(xué)生 , 而每個(gè)學(xué)生只能對(duì)應(yīng)一個(gè)班主任----主表
CREATE TABLE ClassCharger(
id TINYINT PRIMARY KEY auto_increment,
name VARCHAR (20),
age INT ,
is_marriged boolean-- show create table ClassCharger: tinyint(1)
);
INSERT INTO ClassCharger (name,age,is_marriged) VALUES ("冰冰",12,0),
("丹丹",14,0),
("歪歪",22,0),
("姍姍",20,0),
("小雨",21,0);----子表
CREATE TABLE Student(
id INT PRIMARY KEY auto_increment,
name VARCHAR (20),
charger_id TINYINT,--切記:作為外鍵一定要和關(guān)聯(lián)主鍵的數(shù)據(jù)類(lèi)型保持一致--[ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
) ENGINE=INNODB;
INSERT INTO Student(name,charger_id) VALUES ("alvin1",2),
("alvin2",4),
("alvin3",1),
("alvin4",3),
("alvin5",1),
("alvin6",3),
("alvin7",2);
DELETE FROM ClassCharger WHERE name="冰冰";
INSERT student (name,charger_id) VALUES ("yuan",1);-- 刪除居然成功,可是 alvin3顯示還是有班主任id=1的冰冰的;-----------增加外鍵和刪除外鍵---------ALTER TABLE student ADD CONSTRAINT abc
FOREIGN KEY(charger_id)
REFERENCES classcharger(id);
ALTER TABLE student DROP FOREIGN KEY abc;
2、 INNODB支持的ON語(yǔ)句
--外鍵約束對(duì)子表的含義: 如果在父表中找不到候選鍵,則不允許在子表上進(jìn)行insert/update--外鍵約束對(duì)父表的含義: 在父表上進(jìn)行update/delete以更新或刪除在子表中有一條或多條對(duì)--應(yīng)匹配行的候選鍵時(shí),父表的行為取決于:在定義子表的外鍵時(shí)指定的-- on update/on delete子句-----------------innodb支持的四種方式---------------------------------------
-----cascade方式 在父表上update/delete記錄時(shí),同步update/delete掉子表的匹配記錄-----外鍵的級(jí)聯(lián)刪除:如果父表中的記錄被刪除,則子表中對(duì)應(yīng)的記錄自動(dòng)被刪除--------FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE CASCADE------set null方式 在父表上update/delete記錄時(shí),將子表上匹配記錄的列設(shè)為null-- 要注意子表的外鍵列不能為not nullFOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE SET NULL------Restrict方式 :拒絕對(duì)父表進(jìn)行刪除更新操作(了解)------No action方式 在mysql中同Restrict,如果子表中有匹配的記錄,則不允許對(duì)父表對(duì)應(yīng)候選鍵-- 進(jìn)行update/delete操作(了解)
二、多表查詢(xún)
--準(zhǔn)備兩張表--company.employee--company.department
create table employee(
emp_idint auto_increment primary key not null,
emp_name varchar(50),
ageint,
dept_idint);
insert into employee(emp_name,age,dept_id) values
('A',19,200),
('B',26,201),
('C',30,201),
('D',24,202),
('E',20,200),
('F',38,204);
create table department(
dept_idint,
dept_name varchar(100)
);
insert into department values
(200,'人事部'),
(201,'技術(shù)部'),
(202,'銷(xiāo)售部'),
(203,'財(cái)政部');
mysql> select * fromemployee;+--------+----------+------+---------+
| emp_id | emp_name | age | dept_id |
+--------+----------+------+---------+
| 1 | A | 19 | 200 |
| 2 | B | 26 | 201 |
| 3 | C | 30 | 201 |
| 4 | D | 24 | 202 |
| 5 | E | 20 | 200 |
| 6 | F | 38 | 204 |
+--------+----------+------+---------+
6 rows in set (0.00sec)
mysql> select * fromdepartment;+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
| 200 | 人事部 |
| 201 | 技術(shù)部 |
| 202 | 銷(xiāo)售部 |
| 203 | 財(cái)政部 |
+---------+-----------+
4 rows in set (0.01 sec)
1、多表查詢(xún)之連接查詢(xún)
1.笛卡爾積查詢(xún)
mysql> SELECT *FROM employee,department;-- selectemployee.emp_id,employee.emp_name,employee.age,-- department.dept_name fromemployee,department;+--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 1 | A | 19 | 200 | 201 | 技術(shù)部 |
| 1 | A | 19 | 200 | 202 | 銷(xiāo)售部 |
| 1 | A | 19 | 200 | 203 | 財(cái)政部 |
| 2 | B | 26 | 201 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技術(shù)部 |
| 2 | B | 26 | 201 | 202 | 銷(xiāo)售部 |
| 2 | B | 26 | 201 | 203 | 財(cái)政部 |
| 3 | C | 30 | 201 | 200 | 人事部 |
| 3 | C | 30 | 201 | 201 | 技術(shù)部 |
| 3 | C | 30 | 201 | 202 | 銷(xiāo)售部 |
| 3 | C | 30 | 201 | 203 | 財(cái)政部 |
| 4 | D | 24 | 202 | 200 | 人事部 |
| 4 | D | 24 | 202 | 201 | 技術(shù)部 |
| 4 | D | 24 | 202 | 202 | 銷(xiāo)售部 |
| 4 | D | 24 | 202 | 203 | 財(cái)政部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
| 5 | E | 20 | 200 | 201 | 技術(shù)部 |
| 5 | E | 20 | 200 | 202 | 銷(xiāo)售部 |
| 5 | E | 20 | 200 | 203 | 財(cái)政部 |
| 6 | F | 38 | 204 | 200 | 人事部 |
| 6 | F | 38 | 204 | 201 | 技術(shù)部 |
| 6 | F | 38 | 204 | 202 | 銷(xiāo)售部 |
| 6 | F | 38 | 204 | 203 | 財(cái)政部 |
+--------+----------+------+---------+---------+-----------+
2.內(nèi)連接
--查詢(xún)兩張表中都有的關(guān)聯(lián)數(shù)據(jù),相當(dāng)于利用條件從笛卡爾積結(jié)果中篩選出了正確的結(jié)果。select * from employee,department where employee.dept_id =department.dept_id;--select * from employee inner join department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技術(shù)部 |
| 3 | C | 30 | 201 | 201 | 技術(shù)部 |
| 4 | D | 24 | 202 | 202 | 銷(xiāo)售部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
+--------+----------+------+---------+---------+-----------+
3.外連接
--(1)左外連接:在內(nèi)連接的基礎(chǔ)上增加左邊有右邊沒(méi)有的結(jié)果select * from employee left join department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技術(shù)部 |
| 3 | C | 30 | 201 | 201 | 技術(shù)部 |
| 4 | D | 24 | 202 | 202 | 銷(xiāo)售部 |
| 6 | F | 38 | 204 | NULL | NULL |
+--------+----------+------+---------+---------+-----------+
--(2)右外連接:在內(nèi)連接的基礎(chǔ)上增加右邊有左邊沒(méi)有的結(jié)果select * from employee RIGHT JOIN department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技術(shù)部 |
| 3 | C | 30 | 201 | 201 | 技術(shù)部 |
| 4 | D | 24 | 202 | 202 | 銷(xiāo)售部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
| NULL | NULL | NULL | NULL | 203 | 財(cái)政部 |
+--------+----------+------+---------+---------+-----------+
--(3)全外連接:在內(nèi)連接的基礎(chǔ)上增加左邊有右邊沒(méi)有的和右邊有左邊沒(méi)有的結(jié)果--mysql不支持全外連接 full JOIN--mysql可以使用此種方式間接實(shí)現(xiàn)全外連接select * from employee RIGHT JOIN department on employee.dept_id =department.dept_id
UNIONselect * from employee LEFT JOIN department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技術(shù)部 |
| 3 | C | 30 | 201 | 201 | 技術(shù)部 |
| 4 | D | 24 | 202 | 202 | 銷(xiāo)售部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
| NULL | NULL | NULL | NULL | 203 | 財(cái)政部 |
| 6 | F | 38 | 204 | NULL | NULL |
+--------+----------+------+---------+---------+-----------+
-- 注意 union與union all的區(qū)別:union會(huì)去掉相同的紀(jì)錄
2、多表查詢(xún)之復(fù)合條件連接查詢(xún)
--查詢(xún)員工年齡大于等于25歲的部門(mén)
SELECT DISTINCT department.dept_name
FROM employee,department
WHERE employee.dept_id=department.dept_id
AND age>25;--以?xún)?nèi)連接的方式查詢(xún)employee和department表,并且以age字段的升序方式顯示selectemployee.emp_id,employee.emp_name,employee.age,department.dept_namefromemployee,departmentwhere employee.dept_id =department.dept_id
order by age asc;
3、多表查詢(xún)之子查詢(xún)
--子查詢(xún)是將一個(gè)查詢(xún)語(yǔ)句嵌套在另一個(gè)查詢(xún)語(yǔ)句中。--內(nèi)層查詢(xún)語(yǔ)句的查詢(xún)結(jié)果,可以為外層查詢(xún)語(yǔ)句提供查詢(xún)條件。--子查詢(xún)中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關(guān)鍵字-- 還可以包含比較運(yùn)算符:= 、 !=、> 、
(select dept_id fromdepartment);+--------+----------+------+---------+
| emp_id | emp_name | age | dept_id |
+--------+----------+------+---------+
| 1 | A | 19 | 200 |
| 2 | B | 26 | 201 |
| 3 | C | 30 | 201 |
| 4 | D | 24 | 202 |
| 5 | E | 20 | 200 |
+--------+----------+------+---------+
5 rows in set (0.01sec)-- 2. 帶比較運(yùn)算符的子查詢(xún)-- =、!=、>、>=、
--查詢(xún)員工年齡大于等于25歲的部門(mén)select dept_id,dept_name fromdepartmentwheredept_id IN
(select DISTINCT dept_id from employee where age>=25);-- 3. 帶EXISTS關(guān)鍵字的子查詢(xún)--EXISTS關(guān)字鍵字表示存在。在使用EXISTS關(guān)鍵字時(shí),內(nèi)層查詢(xún)語(yǔ)句不返回查詢(xún)的記錄。--而是返回一個(gè)真假值。Ture或False--當(dāng)返回Ture時(shí),外層查詢(xún)語(yǔ)句將進(jìn)行查詢(xún);當(dāng)返回值為False時(shí),外層查詢(xún)語(yǔ)句不進(jìn)行查詢(xún)select * fromemployee
WHERE EXISTS
(SELECT dept_namefrom department where dept_id=203);--department表中存在dept_id=203,Tureselect * fromemployee
WHERE EXISTS
(SELECT dept_namefrom department where dept_id=205);-- Empty set (0.00sec)
ps: create table t1(select * from t2);
三、課后練習(xí)
練習(xí)一:
1、將所有的課程的名稱(chēng)以及對(duì)應(yīng)的任課老師姓名打印出來(lái)
SELECT cid,cname,tname FROM course LEFT JOIN teacher on course.teacher_id=teacher.tid;
2、查詢(xún)學(xué)生表中男女生各有多少人
SELECT gender,COUNT(gender) 人數(shù) FROM student GROUP BY gender;
3、查詢(xún)物理成績(jī)等于100的學(xué)生的姓名
SELECT sid,sname FROM student WHERE sid in (SELECT student_id FROM score WHERE course_id=(SELECT cid FROM course WHERE cname='物理') and num=100);
4、查詢(xún)平均成績(jī)大于八十分的同學(xué)的姓名和平均成績(jī)
SELECT sname,AVG(num) FROM student,score WHERE student.sid=score.student_id GROUP BY student_id HAVING AVG(num)>80;
5、查詢(xún)所有學(xué)生的學(xué)號(hào),姓名,選課數(shù),總成績(jī)
SELECT student_id 學(xué)號(hào) ,sname 姓名,COUNT(course_id) 選課數(shù),SUM(num) 總成績(jī) FROM student,score WHERE student.sid=student_id GROUP BY student_id;
6、查詢(xún)姓李老師的個(gè)數(shù)
SELECT COUNT(tname) 姓李老師個(gè)數(shù) from teacher WHERE tname like '李%';
7、查詢(xún)沒(méi)有報(bào)李平老師課的學(xué)生姓名
SELECT sid,sname FROM student WHERE sid NOT IN (SELECT distinct student_id from score LEFT JOIN student on student_id=student.sid WHERE course_id in (SELECT cid from course,teacher WHERE teacher_id=tid and tname='李平老師'));
mysql> select sid,sname from student where sid not in (SELECT distinct student_id from score where course_id in (SELECT cid from course,teacher WHERE teacher_id=tid and tname='李平老師'));
8、查詢(xún)物理課程比生物課程高的學(xué)生的學(xué)號(hào)
SELECT A.student_id FROM
(SELECT * FROM score WHERE course_id=(SELECT cid FROM course WHERE cname='物理'))A
INNER JOIN
(SELECT * FROM score WHERE course_id=(SELECT cid FROM course WHERE cname='生物')) B ON A.student_id = B.student_id WHERE A.num>B.num
9、查詢(xún)沒(méi)有同時(shí)選修物理課程和體育課程的學(xué)生姓名
SELECT sid,sname from student WHERE sid NOT IN (SELECT student_id from score WHERE course_id in (2,3) GROUP BY student_id HAVING COUNT(student_id)=2);
10、查詢(xún)掛科超過(guò)兩門(mén)(包括兩門(mén))的學(xué)生姓名和班級(jí)
SELECT sname,caption FROM student,class WHERE class_id=cid and sid IN (SELECT student_id FROM score WHERE num<60 GROUP BY student_id HAVING COUNT(student_id)>=2);
11 、查詢(xún)選修了所有課程的學(xué)生姓名
SELECT sname FROM student WHERE sid in (SELECT student_id FROM score ?GROUP BY student_id HAVING COUNT(course_id)=(SELECT COUNT(cid) FROM course));
12、查詢(xún)李平老師教的課程的所有成績(jī)記錄
SELECT sid,sname,cname,num FROM ?student RIGHT JOIN (SELECT student_id,cname,num FROM ?score,course WHERE course_id=cid AND course_id in (SELECT cid from course,teacher WHERE teacher_id=tid and tname='李平老師')) ls on ls.student_id=student.sid;
13、查詢(xún)選課學(xué)生都選修了的課程號(hào)和課程名
SELECT cid,cname FROM course WHERE cid =(SELECT course_id from score GROUP BY course_id HAVING COUNT(student_id)=(select count(distinct student_id) from score))
練習(xí)二:
14、查詢(xún)每門(mén)課程被選修的次數(shù)
SELECT course_id,cname,COUNT(course_id) 被選課次數(shù) FROM score,course WHERE cid=course_id GROUP BY course_id;
15、查詢(xún)只選修了一門(mén)課程的學(xué)生姓名和學(xué)號(hào)
SELECT sid,sname FROM student WHERE sid =(SELECT student_id FROM score GROUP BY student_id HAVING COUNT(course_id)=1);
16、查詢(xún)所有學(xué)生考出的成績(jī)并按從高到低排序(成績(jī)?nèi)ブ?
SELECT DISTINCT num FROM score ORDER BY num DESC;
17、查詢(xún)平均成績(jī)大于85的學(xué)生姓名和平均成績(jī)
SELECT sname,AVG(num) FROM score,student WHERE student_id =student.sid GROUP BY student_id HAVING AVG(num)>85;
18、查詢(xún)生物成績(jī)不及格的學(xué)生姓名和對(duì)應(yīng)生物分?jǐn)?shù)
SELECT sname,num FROM score,student WHERE student_id=student.sid AND course_id=(SELECT cid FROM course WHERE cname='生物') and num<60;
19、查詢(xún)?cè)谒羞x修了李平老師課程的學(xué)生中,這些課程(李平老師的課程,不是所有課程)平均成績(jī)最高的學(xué)生姓名
SELECT student_id,sname,AVG(num) FROM score,student WHERE student_id=student.sid AND course_id in (SELECT cid FROM course WHERE teacher_id =( SELECT tid FROM teacher WHERE tname like '李平%')) GROUP BY student_id ?ORDER BY AVG(num) DESC LIMIT 1;
20、查詢(xún)每門(mén)課程成績(jī)最好的前兩名學(xué)生姓名
21、查詢(xún)不同課程但成績(jī)相同的學(xué)號(hào),課程號(hào),成績(jī)
SELECT * FROM score WHERE student_id IN (SELECT student_id FROM score GROUP BY num,student_id HAVING COUNT(student_id)>=2);
22、查詢(xún)沒(méi)學(xué)過(guò)“李平”老師課程的學(xué)生姓名以及選修的課程名稱(chēng);
SELECT * from score WHERE student_id NOT IN (select distinct student_id from score where course_id in (SELECT cid FROM
course WHERE teacher_id =( SELECT tid FROM teacher WHERE tname like '李平%')));
23、查詢(xún)所有選修了學(xué)號(hào)為1的同學(xué)選修過(guò)的一門(mén)或者多門(mén)課程的同學(xué)學(xué)號(hào)和姓名;
SELECT sid,sname FROM student WHERE sid IN (SELECT DISTINCT student_id FROM score WHERE course_id IN (SELECT course_id from score WHERE student_id=1) AND student_id!=1);
24、任課最多的老師中學(xué)生單科成績(jī)最高的學(xué)生姓名
SELECT sname FROM student WHERE sid IN (SELECT student_id FROM score,(SELECT course_id,MAX(num) 最大值 FROM score WHERE course_id in (SELECT cid FROM course WHERE teacher_id=(SELECT teacher_id FROM course GROUP BY teacher_id ORDER BY COUNT(cid) DESC LIMIT 1)) GROUP BY course_id HAVING max(num)) A WHERE A.最大值=score.num AND score.course_id=A.course_id);
總結(jié)
以上是生活随笔為你收集整理的mysql联表查询多记录显示_数据库:MySQL(多表的表记录的查询)(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql分区有好处吗_mysql 分区
- 下一篇: php mysql 博客制作_PHP实现