兩張假設有兩張表格A和B,把表格當作一個集合,那么表格中的記錄就是集合中的一個元素。
兩張表格如下:
TableA:TableB:
2.1 內連接(只有一種場景)
inner join 或者join(等同於inner join)
或
結果如下:
應用場景:
這種場景下得到的是滿足某一條件的A,B內部的數據;正因為得到的是內部共有數據,所以連接方式稱為內連接。
2.2 外連接(六種場景)
2.2.1 left join 或者left outer join(等同於left join)
或者
結果如下,TableB中更不存在的記錄填充Null:
應用場景:
這種場景下得到的是A的所有數據,和滿足某一條件的B的數據;
2.2.2 [left join 或者left outer join(等同於left join)] + [where B.column is null]
結果如下:
應用場景:
這種場景下得到的是A中的所有數據減去"與B滿足同一條件 的數據",然后得到的A剩余數據;
2.2.3 right join 或者fight outer join(等同於right join)
結果如下,TableB中更不存在的記錄填充Null:
應用場景:
這種場景下得到的是B的所有數據,和滿足某一條件的A的數據;
2.2.4 [left join 或者left outer join(等同於left join)] + [where A.column is null]
結果如下:
應用場景:
這種場景下得到的是B中的所有數據減去 "與A滿足同一條件 的數據“,然后得到的B剩余數據;
2.2.5 full join (mysql不支持,但是可以用 left join union right join代替)
union過后,重復的記錄會合並(id為2,3,4的三條記錄),所以結果如下:
應用場景:
這種場景下得到的是滿足某一條件的公共記錄,和獨有的記錄
2.2.6 full join + is null(mysql不支持,但是可以用 (left join + is null) union (right join+isnull代替)
結果如下:
應用場景:
這種場景下得到的是A,B中不滿足某一條件的記錄之和
注:上面共有其中七(2^3-1)種應用場景,還有一種是全空白,那就是什么都不查,七種情形包含了實際應用所有可能的場景
2.3 交叉連接 (cross join)
2.3.1 實際應用中還有這樣一種情形,想得到A,B記錄的排列組合,即笛卡兒積,這個就不好用集合和元素來表示了。需要用到cross join:
2.3.2 還可以為cross join指定條件 (where):
結果如下;
注:這種情況下實際上實現了內連接的效果
三 注意事項
上面仍然存在遺漏,那就是mysql對sql語句的容錯問題,即在sql語句不完全符合書寫建議的情況,mysql會允許這種情況,盡可能地解釋它:
3.1 一般cross join后面加上where條件,但是用cross join+on也是被解釋為cross join+where;
3.2 一般內連接都需要加上on限定條件,如上面場景2.1;如果不加會被解釋為交叉連接;
3.3 如果連接表格使用的是逗號,會被解釋為交叉連接;
注:sql標准中還有union join和natural inner join,mysql不支持,而且本身也沒有多大意義,其結果可以用上面的幾種連接方式得到
外鍵約束:
創建新聞分類表:news_cate
CREATE TABLE news_cate(
id TINYINT UNSIGNED AUTO_INCREMENT KEY,
cate_name VARCHAR(50) NOT NULL UNIQUE,
cate_desc VARCHAR(100) NOT NULL DEFAULT ' '
);
創建新聞表:news
CREATE TABLE news(
id INT UNSIGNED AUTO_INCREMENT KEY,
title VARCHAR(100) NOT NULL UNIQUE,
content VARCHAR(100) NOT NULL,
cate_id TINYINT UNSIGNED NOT NULL
);
創建成功以后,我們插入一些記錄.
INSERT INTO news_cate(cate_name) values('chineses news'),('glocal news'),('sports news'),('entertainment news');
INSERT INTO news(title,content,cate_id) VALUES('a1','aaa1',1),('a2','aaa2',2),('a3','aaa3',3),('a4','aaa4',4),('a5','aaa5',15);
查詢news表中的id title content,news_cate表中的cate_name
(用到我們剛剛學到的多表聯查)
SELECT n.id,n.title,n.content,c.cate_name from news AS n
JOIN news_cate AS c
ON n.cate_id = c.id;
這時候news_cate新聞分類中,去掉了國際新聞
DELETE FROM news_cate where id = 2;
成功刪除了,但是我們再看看新聞表news,表中的cate_id還有2,顯然這是不合適的
INSERT INTO news(title,content,cate_id) VALUES('a6','aaa6',45);
這條數據也插進去了,這兩個記錄的cate_id,都不在新聞分類里面,這就是所謂的臟數據,此時我們就要用外鍵,來保持數據的一致性和完整性.
創建外鍵的兩種方法:
1 建表時指定外鍵盤:FOREIGN KEY(字段名) REFERENCES 主表(字段名)
注意:子表關聯的必須是父表的主鍵
2動態添加外鍵
ALTER TABLE 表名 drop foreign key 外鍵名
ALTER TABLE 表名 ADD FOREIGN KEY(外鍵字段) REFERENCES 主表(主鍵字段);
**注意,動態添加外鍵時,不能有臟數據,否則不能成功添加外鍵
所以為了自動去掉臟數據,我們把新聞表news刪掉,重新建有外鍵的news表
CREATE TABLE news(
id INT UNSIGNED AUTO_INCREMENT KEY,
title VARCHAR(100) NOT NULL UNIQUE,
content VARCHAR(100) NOT NULL,
cate_id TINYINT UNSIGNED NOT NULL,
FOREIGN KEY(cate_id) REFERENCES news_cate(id)
);
重新插入一下數據,現在非法記錄就不可以插入了,這就是有外鍵和無外鍵的區別和約束
INSERT INTO news(title,content,cate_id) VALUES('a1','aaa1',1),('a2','aaa2',1),('a3','aaa3',3),('a4','aaa4',4),('a5','aaa5',3);
參考連接:https://blog.csdn.net/jintao_ma/article/details/51260458