MySQL 联合查询
聯合查詢
- 笛卡爾積
- 多表查詢一份數據
- join 實現多表查詢
- join 查詢多個表
- 內外連接
- 內連接
- 外連接
- 自連接
- 子查詢
- 使用注意
- 合并查詢
笛卡爾積
笛卡爾積:多表查詢的核心操作。 笛卡爾積的計算很簡單,就類似于排列組合。笛卡爾積是針對任意兩張表之間的運算。
舉例:
笛卡爾積計算過程:先拿第一張表的第一條記錄,和第二張表的每個記錄,分別組合,得到一組新的記錄。然后再拿第一張表的第二條記錄,和第二張表的每條記錄,分別組合,又得到新的記錄,最終得到的記錄就是笛卡爾積。針對兩張表計算笛卡爾積,笛卡爾積的列數,就是 A 的列數 + B 的列數。笛卡爾積的行數,就是 A 的行數 * B 的行數。笛卡爾積的效率不高,但是可以借助來完成發復雜的操作。
笛卡爾積用法:select * from 后面跟上多個表名,表名之間用逗號隔開。
兩張表中都有 班級Id 這一列,班級Id 的值。班級Id 就是連接條件。如果笛卡爾積的兩個列名相同,在寫條件的時候,就可以通過 表名.列名 的方式來訪問。如果列不會混淆,就可以省略表名。代碼如下:
通過 表名.列名 就可以區分了。
多表查詢一份數據
先建表,并且插入數據:
create table classes (id int primary key auto_increment, name varchar(20), `desc` varchar(100));create table student (id int primary key auto_increment, sn varchar(20), name varchar(20), qq_mail varchar(20) ,classes_id int);create table course(id int primary key auto_increment, name varchar(20));create table score(score decimal(3, 1), student_id int, course_id int);建立四個表,然后插入數據:
insert into classes(name, `desc`) values('計算機系2020級1班', '學習了計算機原理、C和Java語言、數據結構和算法'),('中文系2020級3班','學習了中國傳統文學'),('自動化2020級5班','學習了機械自動化');insert into student(sn, name, qq_mail, classes_id) values('09982','黑旋風李逵','xuanfeng@qq.com',1),('00835','菩提老祖',null,1),('00391','白素貞',null,1),('00031','許仙','xuxian@qq.com',1),('00054','不想畢業',null,1),('51234','好好說話','say@qq.com',2),('83223','小菜雞',null,2),('09527','老外學中文','foreigner@qq.com',2);insert into course(name) values ('Java'),('中國傳統文化'),('計算機原理'),('語文'),('高階數學'),('英文');insert into score(score, student_id, course_id) values -- 黑旋風李逵 (70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6), -- 菩提老祖 (60, 2, 1),(59.5, 2, 5), -- 白素貞 (33, 3, 1),(68, 3, 3),(99, 3, 5), -- 許仙 (67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6), -- 不想畢業 (81, 5, 1),(37, 5, 5), -- 好好說話 (56, 6, 2),(43, 6, 4),(79, 6, 6), -- 小菜雞 (80, 7, 2),(92, 7, 6);查找許仙成績,先進行笛卡爾積,不過要指定 student.id = score.student_id; 這兩個匹配,不然就會有很多無效信息。代碼如下:
select * from student,score where student.id = score.student_id;結果如下:
這樣就不會產生無效信息了。所以下一步,我們只需要留下名字是 ”許仙“ 的信息了,所以加一個篩選條件就好了,代碼如下:
select * from student,score where student.id = score.student_id and student.name = '許仙';這樣的結果就是剩 ”許仙“ 了:
最后要的是成績,所以只保留 名字 和 成績 部分就好了:
運行結果如下,這樣就完成了多表查詢一份數據了:
join 實現多表查詢
通過 join 這樣的關鍵字,也可以實現多表查詢,代碼如下:
select student.name, score.score from student join score on student.id = score.student_id and student.name = '許仙';運行結果如下:
join 查詢多個表
通過 select from 表1 join 表2 on 條件 join 表3 on 條件。代碼如下:
select student.name, course.name, score.score from student join score on student.id = score.student_idjoin course on score.course_id = course.id;運行結果如下:
日常使用多表的時候,建議使用 from 多個表 where。
內外連接
使用 join on 可以做到 from where 做不到的事情。上面的 from 多個表 where 寫法叫做 “內連接”,使用 join on 的寫法,既可以表示內連接,還可以表示外連接。
內連接:select 列 from 表1 inner join 表2 on 條件。 inner 表示內連接,其中 inner 可以省略
外連接:
- select 列 from 表1 left join 表2 on 條件; 左外連接
- select 列 from 表1 right join 表2 on 條件; 右外連接
多表查詢的時候,內連接用的最多,但是外連接也會用到。創建兩個表:
create table student(id int, name varchar(20), classId int); create table class(id int,name varchar(20));然后插入數據:
insert into student values (1, '張三', 1); insert into student values (2, '李四', 1); insert into student values (3, '王五', 2); insert into student values (4, '趙六', 3);insert into class values (1, '計算機一班'); insert into class values (2, '計算機二班');內連接
內連接就是要求兩個表里面都要有的數據,代碼如下:
select * from student, class where student.classId = class.id;運行結果如下:
這里的結果少了趙六,因為趙六,只在一個表里面存在。
外連接
左外連接:就是 left join 會以左邊表的記錄為主,盡可能的把記錄都列出來,對于沒有的右邊數據,就改成 null。代碼如下:
select * from student left join class on student.classId = class.id;運行結果如下:
右外連接:就是 right join 會盡量以右邊表的記錄為主,盡可能的吧記錄都列出來,大不了左邊改成 null。
自連接
自己和自己笛卡爾積,處理特殊場景的問題。就是把行轉化為列。因為也是笛卡爾積,所以還是并不高效的方法。不過要指定別名,不然自連接就會重名。在自連接的時候,使用多個條件來完成篩選。代碼如下:
select * from score as s1, score as s2 where s1.student_id = s2.student_id;這樣篩選之后的就是 id 相等的結果了,如果再加一些條件的話,篩選效果就更明顯了:
select * from score as s1, score as s2 where s1.student_id = s2.student_id and s1.course_id=3 and s2.course_id=1;這樣篩選之后的結果就更精確了,運行結果如下:
子查詢
子查詢就是把拆分好的代碼合成一個,單行子查詢:返回一條記錄。例如:查詢之前 “不想畢業” 同學的同班同學。代碼如下:
select classes_id from student where name = '不想畢業';這里就是先查詢出班級,然后再查詢班級為 1 的同學就好了:
select name from student where classes_id = 1;運行結果如下:
將 SQL 語句合并在一起,也就是子查詢:
運行結果如下:
使用注意
在使用子查詢的時候,要把 = 換成 in 來操作。例如要查詢課程成績,先查詢語文和英語的課程,然后再查詢課程的成績。代碼如下:
select id from course where name = '語文' or name = '英文';這里得到課程 id :
然后查詢對應的課程 id 的成績就可以了:
運行結果如下:
然后再合并成一句,代碼如下:
運行結果如下:
合并查詢
合并查詢:把多個查詢語句的結果合并到一起了。通過 union 來實現:把查詢的結果放到一起。對兩個查詢結果取并集。可以自動去重。代碼如下:
select * from course where name = '英文' union select * from course where id < 3;運行結果如下:
也可以使用 or 實現,不過使用 or 的時候必須保證是針對同一個表來進行操作的。代碼如下:
運行結果如下:
總結
以上是生活随笔為你收集整理的MySQL 联合查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 联合查询_MySQL联合查询
- 下一篇: mysql联合查询怎么去重_MySql