Left Join не работает (MySQL) - PullRequest
1 голос
/ 27 июля 2010

У меня есть таблица Книги, в которой я храню данные Книг (ISBN, Названия, Авторы и т. Д.). Чтобы сказать, какие книги являются изданиями друг друга, у меня есть поле Edition_Group_ISBN, которое является произвольным ISBN из группы.

У меня проблемы с получением этого запроса, который должен дать данные Книги и количество других Изданий, основанных на ISBN, для работы:

   SELECT *, Editions_Count 
     FROM Books 
LEFT JOIN ((SELECT Edition_Group_ISBN, COUNT(*) AS Editions_Count 
              FROM Books 
             WHERE Edition_Group_ISBN IN (SELECT Edition_Group_ISBN 
                                            FROM Books)
             GROUP BY Edition_Group_ISBN) AS b 
       ) ON (Books.Edition_Group_ISBN = b.Edition_Group_ISBN 
           AND Books.Edition_Group_ISBN != NULL) 
    WHERE ISBN = 9780140447897

Запрос предоставляет данные книги для 9780140447897, но он дает Editions_Count AS NULL, указывая, что LEFT JOIN не работает.

Ответы [ 2 ]

5 голосов
/ 27 июля 2010

Попробуйте этот более простой запрос:

SELECT b.*, COUNT(*) AS Editions_count
FROM Books b JOIN Books g USING (Edition_Group_ISBN)
WHERE b.ISBN = 9780140447897
GROUP BY b.book_id;

Я думаю, что вы сделали проблему гораздо сложнее, чем нужно.Ваш исходный запрос полон запутанных подзапросов, по крайней мере, один из них совершенно лишний.


Re ваши комментарии:

Да, он отлично работает для сравнения ISBN с несколькими значениями таким образом:

SELECT b.*, COUNT(*) AS Editions_count
FROM Books b JOIN Books g USING (Edition_Group_ISBN)
WHERE b.ISBN IN (9780140447897, 9781934356555)
GROUP BY b.book_id;

COUNT(*) поддерживает только простой подстановочный знак *, что означает подсчет всех строк в группе.

Или вы можете использовать определенное выражение, например COUNT(g.Edition_Group_ISBN), что означает подсчет всех строк в группе, где это выражение не равно нулю.

Но вы не можете использовать g.*, потому что это неоднозначно.Считает ли он все строки в группе?(если так, просто используйте COUNT(*)). Считает ли он ненулевые строки в группе?Что бы это значило в любом случае - считать строки, в которых все столбцы из g не равны нулю или где любые столбцы из g не равны нулю?По этим причинам COUNT(g.*) просто не является допустимой конструкцией в языке SQL.

1 голос
/ 27 июля 2010

Похоже, что запрос включает несколько тавтологий - утверждений, которые всегда верны.

Я думаю, вы можете упростить его до

 SELECT books.*, b.Editions_Count 
     FROM Books 
LEFT JOIN ((SELECT Edition_Group_ISBN, COUNT(*) AS Editions_Count 
              FROM Books 
              GROUP BY Edition_Group_ISBN) AS b 
       ) ON (Books.Edition_Group_ISBN = b.Edition_Group_ISBN) 
 WHERE ISBN = 9780140447897

Подвыбор (WHERE .. IN) и идентификатор условия JOIN! = NULL были избыточными.

Вы можете добиться того же самого, выполнив самостоятельное соединение с Edition_Group_ISBN:

SELECT b.*, count(b2.*)
FROM Books b INNER JOIN Books b2 ON (b.Edition_Group_ISBN=b2.Edition_Group_ISBN)
GROUP BY b.ISBN
HAVING b.ISBN = ...;

EDIT: Исправление заключается в удалении условия JOIN Edition_Group_ISBN! = NULL, поскольку это выражение всегда будет ложным. (Операнд NULL для! = Возвращает результат NLLL.) Таким образом, условие полного соединения становится NULL (false), поэтому левое соединение завершается неудачей.

...