MySQL數(shù)據(jù)庫自連接實例講解
什么是自連接?
自連接可以理解為自己連接自己,在一張表上面所進行的操作;將一張表分成兩張結構和數(shù)據(jù)完全一樣的表(簡單理解:相當于克隆了一張跟自己長得一模一樣的表);
但是問題來了,既然是兩張一模一樣的表,數(shù)據(jù)庫怎么區(qū)分出那張表是哪張表呢?這時候最重要的一個知識點就來了,那就是給兩張表分別取個別名。
自連接語法
自連接我所知道有以下幾種語法,有遺漏的話也歡迎大家在評論區(qū)給我補充出來。
1、內(nèi)連接
1.1隱式內(nèi)連接
select 字段列表 from 表 [as] 表別名1,表 [as] 表別名2 where 條件...;
1.2.顯式內(nèi)連接
select 字段列表 from 表 [as] 表別名1 [inner] join 表 [as] 表別名2 on 條件...;
2、外連接
2.1.左外連接
select 字段列表 from 表 [as] 表別名1 left [outer] join 表 [as] 表別名2 on 條件...;
2.2.右外連接
select 字段列表 from 表 [as] 表別名1 right [outer] join 表 [as] 表別名2 on 條件...;
注:
1.語法和內(nèi)外連接的語法一樣,只不過換成了只在一張表上面操作。
2.[ ] 里面的單詞 as 代表取別名,可寫可不寫;不寫也可以取別名,用哪種都可以啦~??
案例
可以自己插入表和數(shù)據(jù)跟著做一下。
案例演示1
商品表(tb_goods):
create table tb_goods( id int primary key auto_increment comment '主鍵ID', goods varchar(50) not null comment '商品', price decimal(7,2) default 0.00 comment '商品價格' ) comment '商品表';
給商品表插入數(shù)據(jù):
insert into tb_goods(goods,price) values('兒童牙刷',20), ('電動牙刷',10000), ('拼多多牙刷',9.9); insert into tb_goods(goods) values('媽媽給買的牙刷');
數(shù)據(jù)展示:
需求:
查詢比 “拼多多牙刷” 的價格貴的牙刷有哪些?
思路解析(用的是隱式內(nèi)連接),語法:
select 字段列表 from 表 [as] 表別名1,表 [as] 表別名2 where 條件...;
第一步:把 tb_goods(商品表)分成兩張一模一樣的表,分別取 g1 和 g2 兩個別名,把它們連接起來;
select * from tb_goods as g1,tb_goods as g2;
查詢結果如下:它會列出每條數(shù)據(jù)的組合情況,如下,每一種牙刷都能組成四種組合。
第二步:找出 g1 表里面的 “拼多多牙刷”;
select * from tb_goods as g1,tb_goods as g2 where g1.goods = '拼多多牙刷';
查詢結果如下:
根據(jù)上面的語句查詢出來的結果可以看到, g2 表里面的 g2.price 也已經(jīng)把每個牙刷的價格查詢出來了;
第三步:此時,只需要查詢出 g2 所有牙刷的價格(g2.price)大于 g1 “拼多多牙刷”的價格(g1.price)的數(shù)據(jù)就可以了;
select * from tb_goods as g1,tb_goods as g2 where g1.goods = '拼多多牙刷' and g2.price > g1.price;
查詢結果如下:在 g2 表里面,已經(jīng)查出了大于 g1 “拼多多牙刷”的價格數(shù)據(jù)。
第四步:然后就可以把需要的數(shù)據(jù)進行查詢;
select g2.goods,g2.price from tb_goods as g1,tb_goods as g2 where g1.goods = '拼多多牙刷' and g2.price > g1.price;
查詢結果如下:得到了最終結果,比 “拼多多牙刷” 的價格貴的牙刷,完成了需求。
最后,如果要查詢的數(shù)據(jù)更清晰的話,可以給查詢的字段取別名;
select g2.goods as '商品',g2.price as '商品價格' from tb_goods as g1,tb_goods as g2 where g1.goods = '拼多多牙刷' and g2.price > g1.price;
查詢結果如下:
溫馨提醒您:取別名不加 as 也可以,只不過是我自己的個人習慣,嘿嘿~
同樣的,用顯示內(nèi)連接也可以完成該需求:
select g2.* from tb_goods as g1 inner join tb_goods as g2 on g1.goods = '拼多多牙刷' where g2.price > g1.price;
查詢結果如下:
用左外連接也可以完成該需求:
select g2.* from tb_goods as g1 left outer join tb_goods as g2 on g1.goods = '拼多多牙刷' where g2.price > g1.price;
查詢結果如下:
案例演示2
學生表(tb_student):
create table tb_student( id int primary key auto_increment comment '主鍵ID', student_id char(2) not null unique comment '學號', name varchar(50) not null comment '姓名', age tinyint unsigned not null comment '年齡', parent_id char(2) comment '監(jiān)護人ID' )comment '學生表';
給學生表插入數(shù)據(jù):
insert into tb_student(student_id, name, age,parent_id) VALUES('01','大頭兒子',6,'03'), ('03','小頭爸爸',31,null), ('02','小灰灰',5,'04'), ('04','灰太狼',36,null);
數(shù)據(jù)展示:
需求:
查詢學生姓名及學生監(jiān)護人姓名。
思路解析(用的是隱式內(nèi)連接),語法:
select 字段列表 from 表 [as] 表別名1,表 [as] 表別名2 where 條件...;
第一步:把 tb_student(學生表)分成兩張一模一樣的表,分別取 s1 和 s2 兩個別名,把它們連接起來;
select * from tb_student as s1,tb_student as s2;
第二步:看到這個需求,你可能會覺得奇怪,為什么都沒有 學生監(jiān)護人姓名 這個字段,而只有 學生監(jiān)護人ID ;
那是因為我們可以通過 學生監(jiān)護人ID(parent_id) 關聯(lián) 學生學號(student_id),找到該學生的學生監(jiān)護人(student_id)。
比如:大頭兒子的 學生監(jiān)護人ID(parent_id)是 03,此時 03 學生學號(student_id)的家長為小頭爸爸;
SQL 語句編寫:
第一步:把 tb_student(學生表)分成兩張一模一樣的表,分別取 s1 和 s2 兩個別名,把它們連接起來;
select * from tb_student as s1,tb_student as s2;
第二步:找到 s1 表的 學生監(jiān)護人ID(parent_id)和 s2 表的 學生學號(student_id),把它們用 = 關聯(lián)起來,意思就是:通過 學生監(jiān)護人ID(parent_id)找到 學生學號(student_id);
select * from tb_student as s1,tb_student as s2 where s1.parent_id = s2.student_id;
查詢結果如下:從查詢出來的結果,就可以看到對應的 學生姓名(s1.name) 及 學生監(jiān)護人姓名(s2.name) 都已經(jīng)被找到了。
第三步:這時候就可以對學生姓名(s1.name)及學生監(jiān)護人(s2.name)這兩個數(shù)據(jù)進行查詢;
select s1.name,s2.name from tb_student as s1,tb_student as s2 where s1.parent_id = s2.student_id;
查詢結果如下:已經(jīng)實現(xiàn)該需求。
最后,如果要查詢的數(shù)據(jù)更清晰的話,可以給查詢的字段取別名;
select s1.name as '學生姓名',s2.name as '學生監(jiān)護人姓名' from tb_student as s1,tb_student as s2 where s1.parent_id = s2.student_id;
查詢結果如下:
同樣的,用顯示內(nèi)連接也可以完成該需求:
select s1.name '學生姓名',s2.name as '學生監(jiān)護人姓名' from tb_student as s1 inner join tb_student s2 on s1.parent_id = s2.student_id;
查詢結果如下:
擴展需求
在這個學生表(tb_student)里面,家長是沒有歸屬人的,也就是 parent_id 為 <null> 的情況,比如小頭爸爸和灰太狼;
此時,我又有一個需求:我希望查詢 學生姓名 及 學生的監(jiān)護人 姓名,如果學生沒有學生的監(jiān)護人, 也要查詢出來。
此時就不能使用內(nèi)連接了,內(nèi)連接只能查出它們相互交集的數(shù)據(jù);要改成左外連接;
select s1.name '學生姓名',s2.name '學生監(jiān)護人姓名' from tb_student as s1 left join tb_student as s2 on s1.parent_id = s2.student_id;
查詢結果如下:
完。。。
總結
到此這篇關于MySQL數(shù)據(jù)庫自連接實例講解的文章就介紹到這了,更多相關MySQL自連接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
mysql 5.7.17 安裝配置方法圖文教程(windows)
這篇文章主要為大家分享了mysql 5.7.17 安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01union和子查詢中order?by一起使用導致排序失效問題及解決
這篇文章主要介紹了union和子查詢中order?by一起使用導致排序失效問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12mysql 查詢重復的數(shù)據(jù)的SQL優(yōu)化方案
這篇文章主要介紹了mysql 查詢重復的數(shù)據(jù)的SQL優(yōu)化方案,非常不錯的方案推薦給大家。2015-02-02IDEA 鏈接Mysql數(shù)據(jù)庫并執(zhí)行查詢操作的完整代碼
這篇文章主要介紹了IDEA 鏈接Mysql數(shù)據(jù)庫并執(zhí)行查詢操作的完整代碼,代碼不難,詳細大家看完本文肯定有意向不到的收獲,感興趣的朋友跟隨小編一起看看吧2021-05-05MySQL誤刪后使用binlog恢復數(shù)據(jù)的實現(xiàn)方法
這篇文章主要介紹了MySQL誤刪后使用binlog恢復數(shù)據(jù)的實現(xiàn)方法,使用 binlog 恢復數(shù)據(jù)的預期效果是將誤刪的數(shù)據(jù)還原到誤刪之前的狀態(tài),以減少或消除數(shù)據(jù)丟失的影響,文中有相關的代碼示例和圖文介紹,需要的朋友可以參考下2024-05-05