@php
MySQL cross join是mysql中的一種鏈接方式,區別於內鏈接和外鏈接,對於cross join鏈接來講,其實使用的就是笛卡爾鏈接。在MySQL中,當CROSS JOIN不使用WHERE子句時,CROSS JOIN產生了一個結果集,該結果集是兩個關聯表的行的乘積。一般,若是每一個表分別具備n和m行,則結果集將具備n*m行mysql
引用https://www.w3resource.com/mysql/advance-query-in-mysql/mysql-cross-join.php的圖片,如圖演示了cross join的過程,這個過程其實就是笛卡爾鏈接查詢
sql
cross join用法:數據庫
SELECT * FROM t1 CROSS JOIN t2;
注意:cross join的時候是不須要on或者using關鍵字的,這個是區別於inner join和join的函數
若是WHERE在條件表中添加一個子句t1並t2具備關係,則CROSS JOIN該INNER JOIN子句的工做方式相似於如下查詢中所示:翻譯
SELECT * FROM t1 CROSS JOIN t2 WHERE t1.id = t2.id;
ok,再列舉一下cross join表做爲衍生表的例子code
SELECT * FROM table111 LEFT JOIN(table112 CROSS JOIN table113) ON table111.id=table113.id;
ok,介紹了cross join的簡單用法,如今拿http://www.mysqltutorial.org/mysql-cross-join/的例子來介紹:blog
首先,建立一個新數據庫salesdb:圖片
CREATE DATABASE IF NOT EXISTS salesdb;
其次,將當前數據切換到新數據庫testdb:get
USE testdb;
在salesdb數據庫中建立新表:
CREATE TABLE products ( id INT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(100), price DECIMAL(13,2 ) ); CREATE TABLE stores ( id INT PRIMARY KEY AUTO_INCREMENT, store_name VARCHAR(100) ); CREATE TABLE sales ( product_id INT, store_id INT, quantity DECIMAL(13 , 2 ) NOT NULL, sales_date DATE NOT NULL, PRIMARY KEY (product_id , store_id), FOREIGN KEY (product_id) REFERENCES products (id) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (store_id) REFERENCES stores (id) ON DELETE CASCADE ON UPDATE CASCADE );
將數據插入三個表中。假設咱們有三個產品iPhone,iPad而且Macbook Pro其在兩個商店出售North和South。
INSERT INTO products(product_name, price) VALUES('iPhone', 699), ('iPad',599), ('Macbook Pro',1299); INSERT INTO stores(store_name) VALUES('North'), ('South'); INSERT INTO sales(store_id,product_id,quantity,sales_date) VALUES(1,1,20,'2017-01-02'), (1,2,15,'2017-01-05'), (1,3,25,'2017-01-05'), (2,1,30,'2017-01-02'), (2,2,35,'2017-01-05');
ok,業務場景:如今要統計每一個商店每種商品總共營業額是多少錢?
很顯然,用SUM(quantity * price),再group by一下就能夠,這個sql很好寫
SELECT sto.`store_name`, pro.`product_name`, SUM(quantity * price) AS revenue FROM sales sal INNER JOIN stores sto ON sto.`id` = sal.`store_id` INNER JOIN products pro ON sal.`product_id` = pro.`id` GROUP BY sto.`store_name`,pro.`product_name`;
ok,看了一下,發現沒賣出的商品是沒統計出來的,因此不太符合業務需求,業務是要統計全部的商店商品,因此能夠用cross join笛卡爾鏈接,得出全部的商店商品組合數據
笛卡爾查詢組合數據sql:
SELECT a.`store_name`, b.product_name from stores cross join products
前面統計sql已經有了,因此將組合數據SQL和統計數據的SQL進行關聯:
SELECT a.`store_name`, b.product_name, IFNULL(c.revenue, 0) AS revenue FROM stores a CROSS JOIN products b LEFT JOIN (SELECT sto.`id` AS store_id, pro.`id` AS product_id, sto.`store_name`, pro.`product_name`, SUM(quantity * price) AS revenue FROM sales sal INNER JOIN stores sto ON sto.`id` = sal.`store_id` INNER JOIN products pro ON sal.`product_id` = pro.`id` GROUP BY sto.`store_name`, pro.`product_name`) c ON a.id = c.store_id AND b.id = c.product_id ORDER BY a.store_name ;
請注意,IFNULL若是收入爲NULL (在商店沒有銷售的狀況下),查詢使用該函數返回0。
經過CROSS JOIN這種方式使用該子句,您能夠回答普遍的問題,例如,按銷售員,月份查找銷售收入,即便該銷售員在特定月份沒有銷售。
ok,本博客是翻譯兩篇英文博客的:
ok,本博客內容翻譯自兩篇英文博客,不過本博客進行必定修整,將兩篇博客內容進行理解整合成這篇中文博客,緣由是這兩篇博客的例子仍是不錯的,舉出了cross join的經常使用使用場景,固然除了兩篇博客提出的用法,cross join由於其笛卡爾鏈接的特性,還能夠用於批量寫數據,對應批量的寫法,能夠參考我以前的MySQL博客,本博客性質屬於翻譯的,因此轉載請註明出處