запрос: перекрестный продукт вместо объединения - PullRequest
1 голос
/ 06 ноября 2008

У меня есть две таблицы, к которым я хотел бы присоединиться, но я получаю ошибку от 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 ]

8 голосов
/ 06 ноября 2008

Я думаю, что вы хотите

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

Чтобы сопоставить строки из таблиц books и shelf, вам нужно иметь термины от каждой в вашем предложении where - в противном случае вы просто выполняете проверку без операций со строками books, поскольку shelfNum каждой строки будет равно shelfNum.

Как подсказывает @ fixme.myopenid.com, вы также можете пойти по явному маршруту JOIN, но это не обязательно.

5 голосов
/ 06 ноября 2008

, если вы хотите быть уверенным, что вы выполняете объединение, а не перекрестный продукт, вы должны явно указать это в 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

(который вернет все строки с полки)

4 голосов
/ 06 ноября 2008

К вашему сведению: если вы переписываете свои имена, чтобы они были согласованными, все стало намного проще для чтения.

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 не ограничивает строки, вы действительно получаете перекрестный продукт.

1 голос
/ 06 ноября 2008

Проверьте ваш SQL. Ваше предложение where не может быть books. shelfNum = books. shelfNum

А для чего все эти одинарные кавычки?

0 голосов
/ 06 октября 2016

Как уже упоминали другие, проблема, с которой вы столкнулись, была связана с вашим состоянием ВКЛ. Чтобы конкретно ответить на ваш вопрос:

В MySQL, если вы пропустите JOIN, используется INNER JOIN / CROSS JOIN. Для других баз данных это другое. Например, PostgreSQL использует CROSS JOIN, а не INNER JOIN.

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

"В MySQL синтаксические эквиваленты JOIN, CROSS JOIN и INNER JOIN являются синтаксическими эквивалентами (они могут заменять друг друга). В стандартном SQL они не эквивалентны. INNER JOIN используется с предложением ON, CROSS JOIN используется иначе. «

0 голосов
/ 06 ноября 2008

Попробуйте это:

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 не было правильно указано, результат был перекрестным произведением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...