查询:交叉产品而不是连接

时间:2008-11-06 02:56:35

标签: sql cross-product

我有两个表,我想加入,但我收到MySQL的错误

Table: books
bookTagNum ShelfTagNum
book1      1
book2      2
book3      2

Table: shelf
shelfNum   shelfTagNum
1          shelf1
2          shelf2

我希望我的结果是:

bookTagNum ShelfTagNum shelfNum
book1      shelf1           1
book2      shelf2           2
book3      shelf2           2

但我也得到了额外的结果:

book1      shelf2           2

我认为我的查询是在进行交叉产品而不是加入:

SELECT `books`.`bookTagNum` , `books`.`shelfNum` , `shelf`.`shelfTagNum` , `books`.`title`
FROM books, shelf
where `books`.`shelfNum`=`books`.`shelfNum`
ORDER BY `shelf`.`shelfTagNum` ASC
LIMIT 0 , 30

我做错了什么?

6 个答案:

答案 0 :(得分:8)

我想你想要

where `books`.`shelfTagNum`=`shelf`.`shelfNum`

为了匹配booksshelf表中的行,您需要在where子句中包含每个行的术语 - 否则,您只是执行无操作检查books行,因为每一行的shelfNum都等于其shelfNum

正如@ fixme.myopenid.com建议的那样,您也可以使用明确的JOIN路线,但这不是必需的。

答案 1 :(得分:5)

如果你想确定你正在进行连接而不是跨产品,你应该在SQL中明确说明它,因此:

SELECT books.bookTagNum,books.shelfNum, shelf.shelfTagNum, books.title
FROM books INNER JOIN shelf ON books.shelfNum = shelf.shelfTagNum
ORDER BY shelf.shelfTagNum

(只返回两个表中存在的那些行)或:

SELECT books.bookTagNum,books.shelfNum, shelf.shelfTagNum, books.title
FROM books LEFT OUTER JOIN shelf ON books.shelfNum = shelf.shelfTagNum
ORDER BY shelf.shelfTagNum

(将返回书籍中的所有行)或:

SELECT books.bookTagNum,books.shelfNum, shelf.shelfTagNum, books.title
FROM books RIGHT OUTER JOIN shelf ON books.shelfNum = shelf.shelfTagNum
ORDER BY shelf.shelfTagNum

(将返回货架上的所有行)

答案 2 :(得分:4)

仅供参考:如果你重写你的名字是一致的,那么事情会更容易阅读。

Table 1: Book
BookID     ShelfID  BookName
1          1        book1
2          2        book2
3          2        book3

Table 2: Shelf
ShelfID    ShelfName
1          shelf1
2          shelf2

现在,将书籍提取到书架的查询是

SELECT 
 b.BookName,
 s.ShelfName
FROM
 Book b
JOIN Shelf s ON s.ShelfID = b.ShelfID

回答原来的问题:

> where `books`.`shelfNum`=`books`.`shelfNum`
>        ^^^^^--------------^^^^^------------- books repeated - this is an error

WHERE子句,如所写,什么都不做,因为你的where子句不限制任何行,你确实得到了交叉产品。

答案 3 :(得分:1)

检查你的SQL。您的where子句不可能是booksshelfNum = booksshelfNum

这些单引号是什么?

答案 4 :(得分:0)

试试这个:

SELECT `books`.`bookTagNum` , `books`.`shelfNum` , `shelf`.`shelfTagNum` , 
   `books`.`title`
FROM books, shelf
where `books`.`shelftagNum`=`shelf`.`shelfNum`
ORDER BY `shelf`.`shelfTagNum` ASC
LIMIT 0 , 30

由于未正确陈述隐含的JOIN条件,因此结果为叉积。

答案 5 :(得分:0)

正如其他人所提到的,你遇到的问题是你的ON情况。要专门回答你的问题:

在MySQL中,如果省略JOIN,则使用INNER JOIN / CROSS JOIN。对于其他数据库,它是不同的。例如,PostgreSQL使用CROSS JOIN,而不是INNER JOIN。

回复:http://dev.mysql.com/doc/refman/5.7/en/join.html

"在MySQL中,JOIN,CROSS JOIN和INNER JOIN是语法等价物(它们可以互相替换)。在标准SQL中,它们不等效。 INNER JOIN与ON子句一起使用,否则使用CROSS JOIN。"