sql中的join、left join、right join

2012013977發表於2017-07-31
最近在處理商品表、屬性表(一個商品可以有多個屬性也可以沒有屬性)使用到了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;

相關文章