建表SQL
create table account ( account_id bigint PRIMARY KEY AUTO_INCREMENT, name varchar(64) ); create table id_num ( id bigint PRIMARY KEY AUTO_INCREMENT, account_id bigint, id_num varchar(64) ); INSERT INTO account
(account_id
, name
) VALUES (1, '張宇'), (2, '王龍飛'), (3, '聶海生'), (4, '陳同貴'), (5, '宋立嘉'), (11, '鄭天民'), (12, '王顯平'); INSERT INTO id_num
(id
, account_id
, id_num
) VALUES (1, 1, '370205621219253'), (2, 2, '370206501122483'), (3, 3, '370203640507092'), (4, 4, '370206520713161'), (5, 5, '370205551013054'), (6, 5, '370206650615081'), (21, 21, '370206340306481'), (22, 22, '370727770614713');
基礎數據
用戶表,共7條數據:
select * from account;
account_id | name |
---|---|
1 | 張宇 |
2 | 王龍飛 |
3 | 聶海生 |
4 | 陳同貴 |
5 | 宋立嘉 |
11 | 鄭天民 |
12 | 王顯平 |
身份證表,共8條數據:
select * from id_num;
id | account_id | id_num |
---|---|---|
1 | 1 | 370205621219253 |
2 | 2 | 370206501122483 |
3 | 3 | 370203640507092 |
4 | 4 | 370206520713161 |
5 | 5 | 370205551013054 |
6 | 5 | 370206650615081 |
21 | 21 | 370206340306481 |
22 | 22 | 370727770614713 |
分析數據:
用戶1~4都擁有1個身份證號,用戶5擁有2個身份證號碼,用戶11、12沒有登記身份證號碼;
身份證21、22沒有對應用戶。
以下示例都在MySQL中進行了執行及驗證,確保結果正確。
笛卡爾積:****cross join
select * from account cross join id_num;
select * from account join id_num;
account_id | name | id | account_id | id_num |
---|---|---|---|---|
1 | 張宇 | 1 | 1 | 370205621219253 |
2 | 王龍飛 | 1 | 1 | 370205621219253 |
3 | 聶海生 | 1 | 1 | 370205621219253 |
4 | 陳同貴 | 1 | 1 | 370205621219253 |
5 | 宋立嘉 | 1 | 1 | 370205621219253 |
11 | 鄭天民 | 1 | 1 | 370205621219253 |
12 | 王顯平 | 1 | 1 | 370205621219253 |
1 | 張宇 | 2 | 2 | 370206501122483 |
2 | 王龍飛 | 2 | 2 | 370206501122483 |
3 | 聶海生 | 2 | 2 | 370206501122483 |
4 | 陳同貴 | 2 | 2 | 370206501122483 |
5 | 宋立嘉 | 2 | 2 | 370206501122483 |
11 | 鄭天民 | 2 | 2 | 370206501122483 |
12 | 王顯平 | 2 | 2 | 370206501122483 |
1 | 張宇 | 3 | 3 | 370203640507092 |
2 | 王龍飛 | 3 | 3 | 370203640507092 |
3 | 聶海生 | 3 | 3 | 370203640507092 |
4 | 陳同貴 | 3 | 3 | 370203640507092 |
5 | 宋立嘉 | 3 | 3 | 370203640507092 |
11 | 鄭天民 | 3 | 3 | 370203640507092 |
12 | 王顯平 | 3 | 3 | 370203640507092 |
1 | 張宇 | 4 | 4 | 370206520713161 |
2 | 王龍飛 | 4 | 4 | 370206520713161 |
3 | 聶海生 | 4 | 4 | 370206520713161 |
4 | 陳同貴 | 4 | 4 | 370206520713161 |
5 | 宋立嘉 | 4 | 4 | 370206520713161 |
11 | 鄭天民 | 4 | 4 | 370206520713161 |
12 | 王顯平 | 4 | 4 | 370206520713161 |
1 | 張宇 | 5 | 5 | 370205551013054 |
2 | 王龍飛 | 5 | 5 | 370205551013054 |
3 | 聶海生 | 5 | 5 | 370205551013054 |
4 | 陳同貴 | 5 | 5 | 370205551013054 |
5 | 宋立嘉 | 5 | 5 | 370205551013054 |
11 | 鄭天民 | 5 | 5 | 370205551013054 |
12 | 王顯平 | 5 | 5 | 370205551013054 |
1 | 張宇 | 6 | 5 | 370206650615081 |
2 | 王龍飛 | 6 | 5 | 370206650615081 |
3 | 聶海生 | 6 | 5 | 370206650615081 |
4 | 陳同貴 | 6 | 5 | 370206650615081 |
5 | 宋立嘉 | 6 | 5 | 370206650615081 |
11 | 鄭天民 | 6 | 5 | 370206650615081 |
12 | 王顯平 | 6 | 5 | 370206650615081 |
1 | 張宇 | 21 | 21 | 370206340306481 |
2 | 王龍飛 | 21 | 21 | 370206340306481 |
3 | 聶海生 | 21 | 21 | 370206340306481 |
4 | 陳同貴 | 21 | 21 | 370206340306481 |
5 | 宋立嘉 | 21 | 21 | 370206340306481 |
11 | 鄭天民 | 21 | 21 | 370206340306481 |
12 | 王顯平 | 21 | 21 | 370206340306481 |
1 | 張宇 | 22 | 22 | 370727770614713 |
2 | 王龍飛 | 22 | 22 | 370727770614713 |
3 | 聶海生 | 22 | 22 | 370727770614713 |
4 | 陳同貴 | 22 | 22 | 370727770614713 |
5 | 宋立嘉 | 22 | 22 | 370727770614713 |
11 | 鄭天民 | 22 | 22 | 370727770614713 |
12 | 王顯平 | 22 | 22 | 370727770614713 |
笛卡爾乘積是指在數學中,兩個集合X和Y的笛卡尓積(Cartesian product),又稱直積,表示爲X × Y,第一個對象是X的成員而第二個知對象是Y的所有可能有序對的其中一個成員。
直觀的說就是集合A{a1,a2,a3} 集合B{b1,b2},他們的笛卡爾積 是 A*B ={(a1,b1),(a1,b2),(a2,b1),(a2,b2),(a3,b1),(a3,b2)}任意兩個元素道結合在一起。
笛卡爾積存在的意義是什麼?
雖然”笛卡爾積“在實際問題中很少會用到,但”笛卡爾積“不僅僅存在數學意義,也存在現實意義的,比如集合A是一個班的學生,集合B是所有的選修課,A與B的笛卡爾積,表示了學生選擇課程的所有可能性
自然連接:natural join
select * from account natural join id_num;
account_id | name | id | id_num |
---|---|---|---|
1 | 張宇 | 1 | 370205621219253 |
2 | 王龍飛 | 2 | 370206501122483 |
3 | 聶海生 | 3 | 370203640507092 |
4 | 陳同貴 | 4 | 370206520713161 |
5 | 宋立嘉 | 5 | 370205551013054 |
5 | 宋立嘉 | 6 | 370206650615081 |
自然連接是一種特殊的等值連接,他要求兩個關係表中進行連接的必須是相同的屬性列(名字相同),無須添加連接條件,並且在結果中消除重複的屬性列。
內連接:inner join
select * from account a inner join id_num i on a.account_id
= i.account_id
;
select * from account a join id_num i on a.account_id
= i.account_id
;
account_id | name | id | account_id | id_num |
---|---|---|---|---|
1 | 張宇 | 1 | 1 | 370205621219253 |
2 | 王龍飛 | 2 | 2 | 370206501122483 |
3 | 聶海生 | 3 | 3 | 370203640507092 |
4 | 陳同貴 | 4 | 4 | 370206520713161 |
5 | 宋立嘉 | 5 | 5 | 370205551013054 |
5 | 宋立嘉 | 6 | 5 | 370206650615081 |
自然連接和內連接有什麼關係嗎?
“自然連接”和“內連接”的區別,在於對“重合的相同的部分”處理方式不同
1."natrual join 自然連接"的處理方式:既然重複了,就丟掉一份,好比distinct
2.“inner join 內連接”的處理方式:雖然重複,但兩份都保留。
左外連接:left [outer] join
select * from account a left outer join id_num i on a.account_id
= i.account_id
;
select * from account a left join id_num i on a.account_id
= i.account_id
;
account_id | name | id | account_id | id_num |
---|---|---|---|---|
1 | 張宇 | 1 | 1 | 370205621219253 |
2 | 王龍飛 | 2 | 2 | 370206501122483 |
3 | 聶海生 | 3 | 3 | 370203640507092 |
4 | 陳同貴 | 4 | 4 | 370206520713161 |
5 | 宋立嘉 | 5 | 5 | 370205551013054 |
5 | 宋立嘉 | 6 | 5 | 370206650615081 |
11 | 鄭天民 | NULL | NULL | NULL |
12 | 王顯平 | NULL | NULL | NULL |
右外連接:right [outer] join
select * from account a right outer join id_num i on a.account_id
= i.account_id
;
select * from account a right join id_num i on a.account_id
= i.account_id
;
account_id | name | id | account_id | id_num |
---|---|---|---|---|
1 | 張宇 | 1 | 1 | 370205621219253 |
2 | 王龍飛 | 2 | 2 | 370206501122483 |
3 | 聶海生 | 3 | 3 | 370203640507092 |
4 | 陳同貴 | 4 | 4 | 370206520713161 |
5 | 宋立嘉 | 5 | 5 | 370205551013054 |
5 | 宋立嘉 | 6 | 5 | 370206650615081 |
NULL | NULL | 21 | 21 | 370206340306481 |
NULL | NULL | 22 | 22 | 370727770614713 |
union/union all:
select account_id from account union all select account_id from id_num;
account_id |
---|
1 |
2 |
3 |
4 |
5 |
11 |
12 |
1 |
2 |
3 |
4 |
5 |
5 |
21 |
22 |
select account_id from account union select account_id from id_num;
account_id |
---|
1 |
2 |
3 |
4 |
5 |
11 |
12 |
21 |
22 |
全外連接:
select * from account a left join id_num i on a.account_id
= i.account_id
union
select * from account a right join id_num i on a.account_id
= i.account_id
;
account_id | name | id | account_id | id_num |
---|---|---|---|---|
1 | 張宇 | 1 | 1 | 370205621219253 |
2 | 王龍飛 | 2 | 2 | 370206501122483 |
3 | 聶海生 | 3 | 3 | 370203640507092 |
4 | 陳同貴 | 4 | 4 | 370206520713161 |
5 | 宋立嘉 | 5 | 5 | 370205551013054 |
5 | 宋立嘉 | 6 | 5 | 370206650615081 |
11 | 鄭天民 | NULL | NULL | NULL |
12 | 王顯平 | NULL | NULL | NULL |
NULL | NULL | 21 | 21 | 370206340306481 |
NULL | NULL | 22 | 22 | 370727770614713 |
select * from id_num i left join account a on a.account_id
= i.account_id
union
select * from id_num i right join account a on a.account_id
= i.account_id
;
id | account_id | id_num | account_id | name |
---|---|---|---|---|
1 | 1 | 370205621219253 | 1 | 張宇 |
2 | 2 | 370206501122483 | 2 | 王龍飛 |
3 | 3 | 370203640507092 | 3 | 聶海生 |
4 | 4 | 370206520713161 | 4 | 陳同貴 |
5 | 5 | 370205551013054 | 5 | 宋立嘉 |
6 | 5 | 370206650615081 | 5 | 宋立嘉 |
21 | 21 | 370206340306481 | NULL | NULL |
22 | 22 | 370727770614713 | NULL | NULL |
NULL | NULL | NULL | 11 | 鄭天民 |
NULL | NULL | NULL | 12 | 王顯平 |
全外連接(full outer join outer可以省略 )(mysql不支持)
mysql不支持全外連接,using和on的區別在於需要連接的兩個表的屬性名相同的時候使用using和on效果一樣,而屬性名不同的時候必須使用on。