MySQL CROSS JOIN 子句
简介:在本教程中,您将了解MySQL
CROSS JOIN子句以及如何应用它来回答一些有趣的数据问题。
MySQL CROSS JOIN子句简介
CROSS JOIN子句返回连接表中行的笛卡尔积。
假设使用连接两个表CROSS JOIN。结果集将包括两个表中的所有行,其中结果集中的每一行都是第一个表中的行与第二个表中的行的组合。当连接表之间没有关系时会发生这种情况。
注意:如果每个表有1,000行,结果集中将获得1,000 x 1,000 = 1,000,000行,这是巨大的。
下面举例说明的语法CROSS JOIN联接两个表的条款T1和T2:
SELECT
*
FROM
T1
CROSS JOIN
T2;
如果你添加一个WHERE子句,T1并且T2有关系,那么CROSS JOIN就像INNER JOIN下面的查询中所示的子句一样:
SELECT
*
FROM
T1
CROSS JOIN
T2
WHERE
T1.id = T2.id;
MySQL CROSS JOIN子句实例
我们将使用以下testdb数据库和表来演示如何CROSS JOIN工作。
CREATE DATABASE IF NOT EXISTS testdb;
USE testdb;
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
);
涉及三个表:
products表包含产品主数据,其中包括产品ID,产品名称和销售价格。stores表包含销售产品的商店。sales表包含按数量和日期在特定商店中销售的产品。
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');
要获得每个商店和每个产品的总销售额,您需要计算销售额并按商店和产品对其进行分组,如下所示:
SELECT
store_name,
product_name,
SUM(quantity * price) AS revenue
FROM
sales
INNER JOIN
products ON products.id = sales.product_id
INNER JOIN
stores ON stores.id = sales.store_id
GROUP BY store_name , product_name;
运行结果:
+------------+--------------+------------+ | store_name | product_name | revenue | +------------+--------------+------------+ | North | iPad | 8985.0000 | | North | iPhone | 13980.0000 | | North | Macbook Pro | 32475.0000 | | South | iPad | 20965.0000 | | South | iPhone | 20970.0000 | +------------+--------------+------------+ 5 rows in set (0.01 sec)现在,如果您想知道哪个商店没有指定产品的销售,怎么办?上面的查询无法回答这个问题。 要解决此问题,需要使用
CROSS JOIN子句。
首先,您使用CROSS JOIN子句来获取所有商店和产品的组合:
SELECT
store_name, product_name
FROM
stores AS a
CROSS JOIN
products AS b;
运行结果:
+------------+--------------+ | store_name | product_name | +------------+--------------+ | North | iPhone | | South | iPhone | | North | iPad | | South | iPad | | North | Macbook Pro | | South | Macbook Pro | +------------+--------------+ 6 rows in set (0.00 sec)接下来,将上面查询的结果与按商店和按产品返回销售总额的查询相结合。以下查询说明了这个想法:
SELECT
b.store_name,
a.product_name,
IFNULL(c.revenue, 0) AS revenue
FROM
products AS a
CROSS JOIN
stores AS b
LEFT JOIN
(SELECT
stores.id AS store_id,
products.id AS product_id,
store_name,
product_name,
ROUND(SUM(quantity * price), 0) AS revenue
FROM
sales
INNER JOIN products ON products.id = sales.product_id
INNER JOIN stores ON stores.id = sales.store_id
GROUP BY store_name , product_name) AS c ON c.store_id = b.id
AND c.product_id= a.id
ORDER BY b.store_name;
运行结果:
+------------+--------------+---------+ | store_name | product_name | revenue | +------------+--------------+---------+ | North | iPhone | 13980 | | North | Macbook Pro | 32475 | | North | iPad | 8985 | | South | Macbook Pro | 0 | | South | iPad | 20965 | | South | iPhone | 20970 | +------------+--------------+---------+ 6 rows in set (0.02 sec)通过
CROSS JOIN查询方式,可以回答各种各样的问题,例如,即使销售人员在特定月份没有销售,也可以按月查找销售员的销售收入。
