NATURAL JOIN 无法正常工作
NATURAL JOIN does not work properly
我有三个这样描述的表:
+----------+ +-----------------+ +----------+
| products | | products_stores | | stores |
+----------+ +-----------------+ +----------+
| barecode | | #barecode | | storeID |
| name |----| #storeID |----| location |
+----------+ | price | +----------+
+-----------------+
像这样创建它们:
CREATE TABLE IF NOT EXISTS `products` (
`barecode` varchar(100) NOT NULL UNIQUE,
`name` varchar(25) NOT NULL,
PRIMARY KEY (`barecode`)
);
CREATE TABLE IF NOT EXISTS `stores` (
`idStore` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(25) NOT NULL,
`location` varchar(100) NOT NULL,
PRIMARY KEY (`idStore`)
);
CREATE TABLE IF NOT EXISTS `products_stores` (
`idStore` int(10) NOT NULL,
`barecode` VARCHAR(100) NOT NULL,
`price` double NOT NULL,
FOREIGN KEY (`barecode`) REFERENCES `products`(`barecode`),
FOREIGN KEY (`idStore`) REFERENCES `stores`(`idStore`)
);
我想通过正确的商店获得所有产品及其价格,所以我尝试了 NATURAL JOIN 但它没有返回任何内容(代码低于 1-)。因此,我尝试仅使用一个 NATURAL JOIN 来检查它是否有效(代码低于 2- 和 3-)。
1- SELECT * FROM products NATURAL JOIN products_stores NATURAL JOIN stores;
2- SELECT * FROM products JOIN products_stores NATURAL JOIN stores;
3- SELECT * FROM products NATURAL JOIN products_stores JOIN stores;
我不明白为什么 "double" NATURAL JOIN 不起作用。有谁能帮我解决这个问题吗?
谢谢。
这取决于您的数据,这是 documentation 对它的评价
The evaluation of multi-way natural joins differs in a very important
way that affects the result of NATURAL or USING joins and that can
require query rewriting. Suppose that you have three tables t1(a,b),
t2(c,b), and t3(a,c) that each have one row: t1(1,2), t2(10,2), and
t3(7,10). Suppose also that you have this NATURAL JOIN on the three
tables:
SELECT ... FROM t1 NATURAL JOIN t2 NATURAL JOIN t3; Previously, the
left operand of the second join was considered to be t2, whereas it
should be the nested join (t1 NATURAL JOIN t2). As a result, the
columns of t3 are checked for common columns only in t2, and, if t3
has common columns with t1, these columns are not used as equi-join
columns. Thus, previously, the preceding query was transformed to the
following equi-join:
SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c;
That join is missing one more equi-join predicate (t1.a = t3.a). As a
result, it produces one row, not the empty result that it should. The
correct equivalent query is this:
SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c AND
t1.a = t3.a;
简而言之,第二个 JOIN 仅检查前一个 table 的列,而不是第一个 JOIN 的全部结果。
不推荐使用 NATURAL JOIN 的原因之一,没有太多的控制,也没有什么收获。
我有三个这样描述的表:
+----------+ +-----------------+ +----------+
| products | | products_stores | | stores |
+----------+ +-----------------+ +----------+
| barecode | | #barecode | | storeID |
| name |----| #storeID |----| location |
+----------+ | price | +----------+
+-----------------+
像这样创建它们:
CREATE TABLE IF NOT EXISTS `products` (
`barecode` varchar(100) NOT NULL UNIQUE,
`name` varchar(25) NOT NULL,
PRIMARY KEY (`barecode`)
);
CREATE TABLE IF NOT EXISTS `stores` (
`idStore` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(25) NOT NULL,
`location` varchar(100) NOT NULL,
PRIMARY KEY (`idStore`)
);
CREATE TABLE IF NOT EXISTS `products_stores` (
`idStore` int(10) NOT NULL,
`barecode` VARCHAR(100) NOT NULL,
`price` double NOT NULL,
FOREIGN KEY (`barecode`) REFERENCES `products`(`barecode`),
FOREIGN KEY (`idStore`) REFERENCES `stores`(`idStore`)
);
我想通过正确的商店获得所有产品及其价格,所以我尝试了 NATURAL JOIN 但它没有返回任何内容(代码低于 1-)。因此,我尝试仅使用一个 NATURAL JOIN 来检查它是否有效(代码低于 2- 和 3-)。
1- SELECT * FROM products NATURAL JOIN products_stores NATURAL JOIN stores;
2- SELECT * FROM products JOIN products_stores NATURAL JOIN stores;
3- SELECT * FROM products NATURAL JOIN products_stores JOIN stores;
我不明白为什么 "double" NATURAL JOIN 不起作用。有谁能帮我解决这个问题吗? 谢谢。
这取决于您的数据,这是 documentation 对它的评价
The evaluation of multi-way natural joins differs in a very important way that affects the result of NATURAL or USING joins and that can require query rewriting. Suppose that you have three tables t1(a,b), t2(c,b), and t3(a,c) that each have one row: t1(1,2), t2(10,2), and t3(7,10). Suppose also that you have this NATURAL JOIN on the three tables:
SELECT ... FROM t1 NATURAL JOIN t2 NATURAL JOIN t3; Previously, the left operand of the second join was considered to be t2, whereas it should be the nested join (t1 NATURAL JOIN t2). As a result, the columns of t3 are checked for common columns only in t2, and, if t3 has common columns with t1, these columns are not used as equi-join columns. Thus, previously, the preceding query was transformed to the following equi-join:
SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c; That join is missing one more equi-join predicate (t1.a = t3.a). As a result, it produces one row, not the empty result that it should. The correct equivalent query is this:
SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c AND t1.a = t3.a;
简而言之,第二个 JOIN 仅检查前一个 table 的列,而不是第一个 JOIN 的全部结果。
不推荐使用 NATURAL JOIN 的原因之一,没有太多的控制,也没有什么收获。