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;
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;
相關文章
- sql之left join、right join、inner join的區別SQL
- MySQL LEFT JOIN/ INNER JOIN/RIGHT JOINMySql
- sql left join 和 right join解釋SQL
- join、inner join、left join、right join、outer join的區別
- sql的left join 、right join 、inner join之間的區別SQL
- SQL中聯表查詢操作(LEFT JOIN, RIGHT JOIN, INNER JOIN)SQL
- mysql中的left join、right join 、inner join的詳細用法MySql
- 連線查詢簡析 join 、 left join 、 right join
- left join,right join,inner join的條件on和where的區別
- Oracle Left join right jionOracle
- sql:left join和join區別SQL
- oracle的left join,right join和full join的一點介紹(R1)Oracle
- SQL Server Left joinSQLServer
- 【SQL】13 SQL 別名、SQL 連線(JOIN)、SQL INNER JOIN 關鍵字、SQL LEFT JOIN 關鍵字、SQL RIGHT JOIN 關鍵字、SQL FULL OUTER JSQL
- mysql left join轉inner joinMySql
- mysql INNER JOIN、LEFT JOIN、RIGHT JOIN;內連線(等值連線)、左連線、右連線MySql
- LEFT JOIN 和JOIN 多表連線
- sql server left join問題SQLServer
- mysql + left joinMySql
- sql的left join 命令詳解SQL
- Inner Join, Left Outer Join和Association的區別
- mysql常用連線查詢join,left,right,crossMySqlROS
- 兩種連線的表達 :left(right) join 和 (+)
- oracle知識整理(1) union和union all的區別,left join和right join的區別(各種join的區別)Oracle
- 【MySQL】LEFT JOIN 踩坑MySql
- Oracle -- left join 什麼情況可以直接改成joinOracle
- MySql的join(連線)查詢 (三表 left join 寫法)MySql
- SQL joinSQL
- oracle update left join查詢Oracle
- SQL中的Filter, join, semi-join等概念的釋義SQLFilter
- mysql的left join和inner join的效率對比,以及如何優化MySql優化
- 一個left join SQL 簡單優化分析SQL優化
- Oracle中left join中右表的限制條件Oracle
- SQL語句中不同的連線JOIN及SQL中join的各種用法SQL
- Oracle SQL JOINOracleSQL
- SQL -- JOIN子句SQL
- LEFT JOIN 需要注意的點(Presto)REST
- MySQL 之 LEFT JOIN 避坑指南MySql