sql поиск нескольких символов в нескольких книгах - PullRequest
0 голосов
/ 02 марта 2020

Я не могу найти все комиксы с определенными персонажами в них. Таблицы комиксов и символов имеют отношение «многие ко многим» следующим образом:

Моя схема базы данных:

**comics table**
comic_id
comic_name
comic_date

**character table**
character_id
character_name

**comics_character table**
comic_id
character_id

Это прекрасно работает для одного символа:

sqlite3 comics.db

select comic_name 
from comics as c, comics_characters as cc, characters as h 
on c.comic_id = cc.comic_id and h.character_id = cc.character_id 
where h.character_name = 'Superman';

Но если я хочу, чтобы в них были все комиксы, скажем, «Супермен» и «Бэтмен», я попытался использовать это:

sqlite3 comics.db
select comic_name 
from comics as c, comics_characters as cc, characters as h 
on c.comic_id = cc.comic_id and h.character_id = cc.character_id 
where h.character_name in ('Batman', 'Superman');

, но я получаю только список комиксов с участием «Бэтмена» или «Супермена», а не комиксы с «Бэтменом» и «Суперменом» в

Я также пробовал это, что ничего не возвращает:

sqlite3 comics.db
select comic_name 
from comics as c, comics_characters as cc, characters as h 
on (c.comic_id = cc.comic_id and h.character_id = cc.character_id) 
where (h.character_name = 'Batman' and h.character_name = 'Superman');

Я пробовал другие варианты, но не могу получить желаемый результат

1 Ответ

0 голосов
/ 02 марта 2020

Маршрут ИЛИ не работает по причинам, которые вы сработали - вы получаете строки для супермена или бэтмена, а комиксы, в которых оба персонажа имеют две строки с одинаковыми комиксами c и разными идентификаторами символов. Маршрут AND не работает, потому что строка не может быть одновременно обоими символами.

Итак, вам нужно использовать маршрут ИЛИ, чтобы получить комиксы с одним или обоими персонажами, а затем также использовать счетчик, чтобы показывать только комиксы с обоими персонажами. По сути, «фильтруйте по супермену или бэтмену, а затем фильтруйте снова только по идентификаторам comi c, которые появляются в двух строках» или «фильтруйте только по бэтмену или супермену, а затем группируйте их на основе comi c is и принимайте только группы которые имеют две сущности в них ". В конечном счете, урок здесь заключается в том, что строки базы данных рассматриваются как разные сущности, и когда вы хотите рассматривать их как одну, вы должны сгруппировать их, поэтому мы определяем комиксы на основе некоторого атрибута группы после ( намеренно) потерять детали того, какие именно объекты содержит группа:

SELECT comic_id
FROM comic_characters
WHERE character_id IN (1,2) --Batman or Superman
GROUP BY conic_id
HAVING COUNT(*) = 2

Число в правой части = должно совпадать с числом идентификаторов символов в предложении IN (). Если вы IN для 4-х символьных идентификаторов, тогда используйте COUNT(*) = 4

. Вы можете объединяться в другие таблицы, чтобы вы могли использовать имена и т.д .; Я упростил это, чтобы сделать точку без посторонних деталей


Сноска; эта техника найдет комиксы, в которых есть, по крайней мере, Бэтмен и Супермен. Коми c вполне может содержать и других персонажей, но мы потеряли этих парней на стадии WHERE до того, как сделали GROUP BY. Если вы хотели комиксы, в которых были ТОЛЬКО Бэтмен и Супермен, это другое дело. Для этого мы могли бы сначала сделать что-то вроде группировки и условного подсчета - дать Бэтмену или Супермену 1 балл, а всем остальным 10 баллов, комиксы, в которых были только B и S, получат 2 балла, комиксы с одним из них - 1, и присутствие кого-либо еще может привести к 10 или более баллам, поэтому мы можем отфильтровать 2

...