MySQL: выберите записи, у которых нет транзитивных дочерних записей. - PullRequest
1 голос
/ 28 мая 2020

Я проиллюстрирую свой вопрос, поскольку понимаю, что это очень сбивает с толку.

Допустим, у вас есть три таблицы (данные несовместимы, это только для иллюстративных целей):

Категория

+----+----------+
| id | name     |
+----+----------+
| 1  | History  |
| 2  | Sci-fi   |
| 3  | Mystery  |
+----+----------+

Книга

+----+-----------------------------+
| id | category_id | name          |
+----+-------------+---------------+
| 1  | 5           | Mowgli        |
| 2  | 7           | Don Quixote   |
| 3  | 11          | Ulysses       |
+----+-------------+---------------+

Теги

+----+---------+-------------+
| id | book_id | name        |
+----+---------+-------------+
| 1  | 452     | Bestseller  |
| 2  | 42      | Novel       |
| 3  | 921     | Novelty     |
+----+---------+-------------+

Мне нужно выбрать все неназначенные теги для каждая книга.

Ниже приведен запрос, который просто показывает все теги для каждой категории, для каждой книги, где мне нужно (я повторяюсь здесь), чтобы выбрать только те теги, которые назначены любой другой книге, но не текущий.

Другими словами, чтобы выбрать только те теги, которые еще не были присвоены книге.

SELECT c.id category_id, b.name, t.book_id, t.id tag_id 
FROM tags t
LEFT JOIN book b ON b.id=t.book_id
LEFT JOIN category c ON c.id=b.category_id 

1 Ответ

3 голосов
/ 28 мая 2020

Идея состоит в том, чтобы использовать cross join для создания всех комбинаций книг и тегов. Затем используйте left join или другой метод, чтобы отфильтровать уже существующие:

select b.*, t.name
from (select distinct name from tags) t cross join
     books b left join
     tags tt
     on tt.book_id = b.id and tt.name = t.name
where tt.book_id is null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...