Mysql多表查詢筆記

MySQL鏈接的種類,JOIN左邊(前邊)的表是左邊,右邊(後邊)的是右表html

  • 逗號:作笛卡爾集鏈接
  • INNER JOIN: 若是表中有至少一個匹配,則返回行
  • LEFT JOIN: 即便右表中沒有匹配,也從左表返回全部的行
  • RIGHT JOIN: 即便左表中沒有匹配,也從右表返回全部的行
  • NATURAL  JOIN
  • NATURAL LEFT JOIN
  • NATURAL RIGHT JOIN
  • CROSS JOIN

mysql

  • MySQL不支持FULL JOIN(只要其中一個表中存在匹配,就返回行),能夠結合使用UNION、LEFT/RIGHT JOIN來實現;
  • MySQL中LEFT/INNER JOIN還能夠寫成LEFT/INNER OUTER JOIN;
  • CROSS JOIN在標準SQL中是不帶ON子句的,做用是生成笛卡爾積,在MySQL中CROSS JOIN後帶ON子句時,CROSS會被忽略,就至關於JOIN;
  • 不使用ON子句時,JOIN和INNER JOIN和CROSS JOIN和逗號是等價的,作笛卡爾積;
  • 使用ON子句時,INNER/LEFT/RIGHT JOIN不會生成笛卡爾集,直接根據條件生成臨時表
  • 逗號操做符和其餘幾種鏈接操做符的優先級不一樣,儘可能不要同時使用避免出錯。
  • 使用逗號鏈接加where子句和使用INNER JOIN加ON子句效果同樣
  • join、inner join、cross join支持on和using語法,逗號不支持on和using語法

多表查詢的過程sql

  1. 由多張表生成一張臨時表(有on子句時由on子句中的條件生成)
  2. 使用JOIN的方式以及ON子句後面的條件進行篩選
  3. 使用使用WHERE子句後面的條件篩選
  4. 使用GROUP BY條件分組
  5. 使用HAVING+聚合函數篩選
  6. 使用ORDER BY排序
  7. 使用LIMIT篩選

 

假設對錶a、b、c進行聯合查詢yii

提示錯誤:Unknown column 'xxx' in 'on clause'函數

緣由是FROM後面的兩張表沒有使用括號包裹起來oop

--錯誤的寫法
select * from a,b left join c on 條件 where  條件

--正確的寫法
select * from (a,b) left join c on 條件 where 條件

若是左鏈接時某個字段爲空,就讓他等於另一個字段,使用IFNULL()優化

SELECT
	h.id AS id,
	h.goods_id AS goodsId,
	g.goods_advert AS goodsAdvert,
	IFNULL(aos.activity_price,g.sell_price) AS sellPrice,--注意g.sell_price不能用別名price代替
	g.goods_name AS goodsName,
	g.logo_url AS logoUrl,
	g.is_delivery AS isDelivery,
	g.sell_price AS price
FROM
	(tb_house h,
	tb_goods g)
 LEFT JOIN tb_aos_goods_rt aos ON h.goods_id = aos.goods_id
WHERE
	1 = 1
AND h.member_id = 107
AND h.goods_id = g.id
AND h. STATUS = 1
ORDER BY
	h.create_date DESC

若是某條數據的aos.activity_price爲null,最後的結果集要以sellPrice排序,ORDER by後面應該寫別名sellPrice而不是寫aos.activity_priceurl

CROSS JOIN的用法:http://www.yiibai.com/mysql/cross-join.htmlspa

左右鏈接可否同時使用code

SQL 定義了兩種不一樣語法方式去表示"鏈接"。首先是"顯式鏈接符號",它顯式地使用關鍵字 JOIN,其次是"隱式鏈接符號",它使用所謂的"隱式鏈接符號"。隱式鏈接符號把須要鏈接的表放到 SELECT 語句的 FROM 部分,並用逗號隔開。這樣就構成了一個"交叉鏈接",WHERE 語句可能放置一些過濾謂詞(過濾條件)。那些過濾謂詞在功能上等價於顯式鏈接符號. SQL 89標準只支持內部鏈接與交叉鏈接,所以只有隱式鏈接這種表達方式;SQL 92標準增長了對外部鏈接的支持,這纔有了JOIN表達式。

 

逗號鏈接加where子句和inner join加on子句的異同

在查詢條件相同時它們的查詢結果是相同的,可是查詢的過程不徹底相同;

使用逗號操做符加where子句:首先生成笛卡爾積,由於在沒有on子句時,逗號和CROSS JOIN是相同的,而後經過條件去過濾。

使用inner join加on子句:直接經過條件去過濾生成臨時表,不會生成笛卡爾集,速度更快

開啓優化參數後MySQL會自動優化,一般使用,不會形成資源浪費;不使用逗號,所有使用JOIN是最好的,這樣既不會由於運算符優先級不一樣而出錯,也不會由於沒有開啓優化參數而形成資源浪費。

 

join的方式不一樣,cross join生成的是先生成笛卡爾集,而後on鏈接條件被視爲了filter用於數據過濾,inner join是直接基於join condition作鏈接,生成的join集合就是最終的輸出結果,產生的中間數據更小。實際上MySQL優化器會將這兩條查詢都優化成同一種join方式,好比merge join或者nested loop join,若是你沒有開啓對應的優化參數,那麼MySQL只有傻傻的去按指定的方式去作join

查詢條件放在ON後面和放在WHERE後面有什麼差別

有上可知,在沒有ON時,INNER JOIN和CROSS JOIN是同樣的 ,因此推薦使用INNER JOIN ON代替逗號加WHERE;

ON條件是生成臨時表時使用的條件,與JOIN的類型有關,不一樣類型產生的臨時表也不一樣,WHERE條件時在臨時表生成以後進行篩選的條件,在LEFT或RIGHT JOIN中條件是不能隨便放的

在where後面有多個條件時使用加個1=1的緣由

相關文章
相關標籤/搜索