sql中的join、left join、right join

最近在處理商品表、屬性表(一個商品可以有多個屬性也可以沒有屬性)使用到了join,在此總結一下
1.left join(左連接) 返回左表中的所有記錄和右表中關聯字段相等的記錄
2.right join(右連接) 返回右表中的所有記錄和左表中關聯字段相等的記錄
3.inner join(等值連接、內連接) 只返回兩個表中關聯字段相等的記錄
商品表:(goods_id是關聯字段)
+----------+------------+-------------+-------------+----------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn |
+----------+------------+-------------+-------------+----------+
|        1 | 襯衫       | 100         | 10          | 201701   |
|        2 | 短褲       | 200         | 10          | 201702   |
|        3 | 秋褲       | 300         | 10          | 201703   |
|        4 | 毛衣       | 400         | 10          | 201704   |
+----------+------------+-------------+-------------+----------+
屬性表:
+----+----------+-------+------+--------+
| id | goods_id | color | size | weight |
+----+----------+-------+------+--------+
|  1 |        1 | 黑色1 |    3 |      3 |
|  2 |        1 | 黑色2 |    3 |      3 |
|  3 |        2 | 黑色3 |    3 |      3 |
|  4 |        3 | 黑色4 |    3 |      3 |
|  5 |        5 | 黑色5 |    3 |      3 |
+----+----------+-------+------+--------+
1.左連接sql:select g.*,a.* from goods as g left join attr as a on g.goods_id = a.goods_id;
+----------+------------+-------------+-------------+----------+------+----------+-------+------+--------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn | id   | goods_id | color | size | weight |
+----------+------------+-------------+-------------+----------+------+----------+-------+------+--------+
|        1 | 襯衫       | 100         | 10          | 201701   |    1 |        1 | 黑色1 |    3 |      3 |
|        1 | 襯衫       | 100         | 10          | 201701   |    2 |        1 | 黑色2 |    3 |      3 |
|        2 | 短褲       | 200         | 10          | 201702   |    3 |        2 | 黑色3 |    3 |      3 |
|        3 | 秋褲       | 300         | 10          | 201703   |    4 |        3 | 黑色4 |    3 |      3 |
|        4 | 毛衣       | 400         | 10          | 201704   | NULL | NULL     | NULL  | NULL | NULL   |
+----------+------------+-------------+-------------+----------+------+----------+-------+------+--------+
需要注意的是:
1)如果兩張表都是查詢所有(即 *),就會導致關聯字段的重複,當後面的字段覆蓋了前面的字段,就有可能出現NULL值;
2)沒有匹配的值都是NULL
2.右連接sql:略
3.內連接sql:select g.*,a.* from goods as g inner join attr as a on g.goods_id = a.goods_id;
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn | id | goods_id | color | size | weight |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
|        1 | 襯衫       | 100         | 10          | 201701   |  1 |        1 | 黑色1 |    3 |      3 |
|        1 | 襯衫       | 100         | 10          | 201701   |  2 |        1 | 黑色2 |    3 |      3 |
|        2 | 短褲       | 200         | 10          | 201702   |  3 |        2 | 黑色3 |    3 |      3 |
|        3 | 秋褲       | 300         | 10          | 201703   |  4 |        3 | 黑色4 |    3 |      3 |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
同樣需要注意重複字段的問題


這裏用到了on後接條件語句,順便查了下on、where、having的區別
1.有where的sql:select g.*,a.* from goods as g inner join attr as a on g.goods_id = a.goods_id where g.goods_id = 1;
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
| goods_id | goods_name | goods_price | goods_mount | goods_sn | id | goods_id | color | size | weight |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
|        1 | 襯衫       | 100         | 10          | 201701   |  1 |        1 | 黑色1 |    3 |      3 |
|        1 | 襯衫       | 100         | 10          | 201701   |  2 |        1 | 黑色2 |    3 |      3 |
+----------+------------+-------------+-------------+----------+----+----------+-------+------+--------+
注意where的位置一定要在on後面,否則會報錯;ON根據限制條件對數據庫記錄進行過濾,然後生產臨時表;而WHERE是在臨時表生產之後,根據限制條件從臨時表中篩選結果。
2.有關區別解釋:
1)on、where、having這三個都可以加條件的子句中,on是最先執行,where次之,having最後。有時候如果這先後順序不影響中間結果的話,那最終結果是相同的。但因爲on是先把不符合條件的記錄過濾後才進行統計,它就可以減少中間運算要處理的數據,按理說應該速度是最快的。
2)on只有在多表聯查時纔會用到,在多表聯接查詢時,on比where更早起作用。系統首先根據各個表之間的聯接條件,把多個表合成一個臨時表後,再由where進行過濾
3)HAVING不能單獨出現,只能出現在GROUP BY子句中,HAVING是在聚集函數計算結果出來之後篩選結果,查詢結果只返回符合條件的分組
例如sql:select goods_name from goods group by goods_name having sum(goods_price) < 400;
+------------+
| goods_name |
+------------+
| 短褲       |
| 秋褲       |
| 襯衫       |
+------------+
一定要出現分組和聚集函數
用到了distinct,簡單記錄下去重複:
select *,count(distinct goods_mount) from goods;
發佈了79 篇原創文章 · 獲贊 21 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章