Python全棧之路系列之MySQL連表查詢
普通的連表查詢,把一個select
的結果當作另外一個select
的參數
SELECT * FROM personnel.person_info where personnel.person_info.part_nid in (SELECT nid from personnel.part WHERE personnel.part.caption="XO股份有限公司公司-技術部-Python開發");
顯示結果
+-----+---------+------------------+-------------+----------+----------+---------+ | nid | name | email | phone | part_nid | position | caption | +-----+---------+------------------+-------------+----------+----------+---------+ | 1 | as | [email protected] | 13800138000 | 5 | Python | NULL | | 2 | ansheng | [email protected] | 13800138000 | 5 | Python | NULL | | 3 | a | [email protected] | 13800138000 | 5 | Python | NULL | | 4 | v | [email protected] | 13800138000 | 5 | Python | NULL | | 5 | b | [email protected] | 13800138000 | 5 | Python | NULL | | 6 | w | [email protected] | 13800138000 | 5 | Python | NULL | +-----+---------+------------------+-------------+----------+----------+---------+ 6 rows in set (0.00 sec)
join進行連表查詢
SQL指令
select * from personnel.person_info left join personnel.part on personnel.person_info.part_nid = personnel.part.nid where personnel.part.caption = 'XO股份有限公司公司-技術部-Python開發';
顯示結果
+-----+---------+------------------+-------------+----------+----------+---------+------+---------------------------------------------------+ | nid | name | email | phone | part_nid | position | caption | nid | caption | +-----+---------+------------------+-------------+----------+----------+---------+------+---------------------------------------------------+ | 1 | as | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 2 | ansheng | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 3 | a | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 4 | v | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 5 | b | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 6 | w | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | +-----+---------+------------------+-------------+----------+----------+---------+------+---------------------------------------------------+ 6 rows in set (0.00 sec)
上面的意思是查詢personnel.person_info.part_nid
列的字段和personnel.part.nid
一樣的數據,並且personnel.part.caption = 'XO股份有限公司公司-技術部-Python開發'
參數 | 實例 | 描述 |
---|---|---|
left join | tb1 left join tb2 | 左外鏈接 |
right join | tb1 right join tb2 | 右外鏈接 |
inner join | tb1 inner join tb2 | 內鏈接 |
Full Join | - | 全外連接 |
CROSS | - | 交叉鏈接,又稱笛卡爾鏈接或叉乘 |
left join
tb1爲主,tb2爲輔,將A中所有的數據羅列出來
tb2則只顯示與tb1對應的數據
執行以下語句在person_info
表中插入一條數據
INSERT INTO personnel.person_info (NAME,email,phone,part_nid,position) VALUES("aa","[email protected]",13800138000,3,"DBA");
通過left jion
進行查詢
mysql> use personnel Database changed mysql> select * from person_info LEFT JOIN part on person_info.part_nid = part.nid WHERE part.nid = 3; +-----+------+--------------+-------------+----------+----------+---------+------+------------------------------------------+ | nid | name | email | phone | part_nid | position | caption | nid | caption | +-----+------+--------------+-------------+----------+----------+---------+------+------------------------------------------+ | 9 | aa | [email protected] | 13800138000 | 3 | DBA | NULL | 3 | XO股份有限公司公司-技術部-DBA | +-----+------+--------------+-------------+----------+----------+---------+------+------------------------------------------+ 1 row in set (0.00 sec)
這樣他就只把我們剛剛插入的那條數據查詢了除了,即查詢person_info
表中的內容,part
表中的列作爲person_info
表的查詢條件,如果person_info
表中的part_nid
列如果等於part
表中nid
列,那麼就顯示數據。
inner join
自動忽略兩張表沒有建立關聯數據
只返回兩個表中鏈接字段相等的數據
select * from person_info inner JOIN part on person_info.part_nid = part.nid;
顯示結果
+-----+---------+------------------+-------------+----------+----------+---------+-----+---------------------------------------------------+ | nid | name | email | phone | part_nid | position | caption | nid | caption | +-----+---------+------------------+-------------+----------+----------+---------+-----+---------------------------------------------------+ | 1 | as | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 2 | ansheng | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 3 | a | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 4 | v | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 5 | b | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 6 | w | [email protected] | 13800138000 | 5 | Python | NULL | 5 | XO股份有限公司公司-技術部-Python開發 | | 9 | aa | [email protected] | 13800138000 | 3 | DBA | NULL | 3 | XO股份有限公司公司-技術部-DBA | +-----+---------+------------------+-------------+----------+----------+---------+-----+---------------------------------------------------+ 7 rows in set (0.00 sec)
MySQL Full Join的實現
把左右兩個表的數據都取出來,不管是否匹配
MySQL Full Join
的實現 因爲MySQL不支持FULL JOIN
,下面是替代方法
語法
select * from A left join B on A.id = B.id (where 條件) union --all可選 select * from A right join B on A.id = B.id (where條件);
CROSS
如果A和B是兩個集合,他們的交叉連接就記爲:AxB
mysql> use personnel Database changed mysql> SELECT * from course; +-----+--------+ | Cno | Cname | +-----+--------+ | 1 | 足球 | | 2 | 籃球 | | 3 | 排球 | +-----+--------+ 3 rows in set (0.00 sec) mysql> SELECT * from student; +-----+--------+ | Sno | Name | +-----+--------+ | 1 | 張三 | | 2 | 李四 | | 3 | 王五 | +-----+--------+ 3 rows in set (0.00 sec) mysql> SELECT * FROM course CROSS JOIN student; +-----+--------+-----+--------+ | Cno | Cname | Sno | Name | +-----+--------+-----+--------+ | 1 | 足球 | 1 | 張三 | | 2 | 籃球 | 1 | 張三 | | 3 | 排球 | 1 | 張三 | | 1 | 足球 | 2 | 李四 | | 2 | 籃球 | 2 | 李四 | | 3 | 排球 | 2 | 李四 | | 1 | 足球 | 3 | 王五 | | 2 | 籃球 | 3 | 王五 | | 3 | 排球 | 3 | 王五 | +-----+--------+-----+--------+ 9 rows in set (0.00 sec)
一對多,多表查詢
創建color
表
CREATE TABLE `color` ( `nid` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(32) DEFAULT NULL, PRIMARY KEY (`nid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
往color
表中添加兩條數據
insert into color(title) values('red'),('yellow');
person_info
表添加color_nid
列,類型是int
alter table person_info add color_nid int;
把person_info
表中的color_nid
列和color
表中的nid
列做一個外鍵關聯
alter table person_info add constraint person_ibfk_2 foreign key person_info(`color_nid`) REFERENCES color(`nid`);
往person_info
表中插入一條數據
INSERT INTO personnel.person_info (NAME,email,phone,part_nid,position,color_nid) VALUES("b", "b.ansheng.me",13800138000,3,"DBA",1)
查詢職位是XO股份有限公司公司-技術部-DBA
,顏色是yellow
的的人員
SELECT * FROM person_info LEFT JOIN part ON person_info.part_nid = part.nid LEFT JOIN color ON person_info.color_nid = color.nid WHERE color.title = "yellow";
多對多關係及查詢
先創建三張表
student(學生表)
CREATE TABLE `student` ( `Sno` int(11) NOT NULL AUTO_INCREMENT, `Name` char(20) NOT NULL, PRIMARY KEY (`Sno`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
course(課程表)
CREATE TABLE `course` ( `Cno` int(11) NOT NULL AUTO_INCREMENT, `Cname` char(10) NOT NULL, PRIMARY KEY (`Cno`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
student_course(關係表)
CREATE TABLE `student_course` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `Sno` int(11) NOT NULL, `Cno` int(11) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
設置外鍵關聯
ALTER TABLE student_course ADD CONSTRAINT student_course_to_student_ibfk_2 FOREIGN KEY student_course (`Sno`) REFERENCES student (`Sno`); ALTER TABLE student_course ADD CONSTRAINT student_course_to_course_ibfk_1 FOREIGN KEY student_course (`Cno`) REFERENCES course (`Cno`);
往course(課程表)
中插入數據
INSERT INTO course(Cname) VALUES("足球"),("籃球"),("排球");
往student(學生表)
中插入數據
INSERT INTO student(Name) VALUES("張三"),("李四"),("王五");
student_course(關係表)
插入數據
INSERT INTO student_course(Sno,Cno) VALUES(2,1),(2,3),(3,3),(3,1),(1,2),(3,2);
顯示學生所選的課程SQL指令
SELECT s.Name,C.Cname FROM student_course AS sc LEFT JOIN student AS s ON s.Sno=sc.Sno LEFT JOIN course AS c ON c.Cno=sc.Cno;
結果如下:
+--------+--------+ | Name | Cname | +--------+--------+ | 張三 | 籃球 | | 李四 | 足球 | | 李四 | 排球 | | 王五 | 排球 | | 王五 | 足球 | | 王五 | 籃球 | +--------+--------+ 6 rows in set (0.00 sec)