2015-08-17 2 views
2

У меня есть 2 таблицы с именем tags и things, оба из которых содержат id и столбец name. Затем есть третий стол: thing_tags. Какие есть данные, как это:MySQL получает уникальный список вещей с несколькими идентификаторами тегов

╔═══════╤═════════╗ 
║ tagid │ thingid ║ 
╟───────┼─────────╢ 
║  6 │  1 ║ 
║  6 │  2 ║ 
║ 12 │  1 ║ 
║ 12 │  2 ║ 
║ 12 │  3 ║ 
║ 15 │  4 ║ 
║ 16 │  4 ║ 
║ 21 │  5 ║ 
╚═══════╧═════════╝

В 2 колонки имеют внешних ключей ссылки на id столбце соответствующих таблиц.

То, что я хотел бы сделать это, чтобы получить список уникальных идентификаторов вещи, которые имеют как тег # 6 и # 12, так что в этом случае результат будет идентификаторы 1 и 2, но не 3, то найдите элементы с этими идентификаторами в таблице things и извлеките их. Вот мой текущий SQL-запрос:

SELECT th.* 
FROM thing_tags t 
LEFT JOIN things th ON t.id = th.id 
WHERE t.id IN (12,6) 
ORDER BY th.name ASC 

Это не работает так, как я хочу его, так как он также дает мне 3-й вещь из таблицы, и возвращает правильные результаты несколько раз. Как я могу изменить этот запрос так, чтобы возвращались только те things, которые привязаны ко всем указанным tagid s, а не только одному, без дубликатов строк в конце?

ответ

3

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

SELECT field1, COUNT(field2) AS cnt 
FROM yourtable 
WHERE field2 IN (6, 12) 
GROUP BY field1 
HAVING cnt = 2 

count() говорит вам, сколько из in поле, и затем вы используете предложение having, чтобы обеспечить, насколько вы действительно хотите иметь. В вашем случае вам нужно только 2, поэтому вы используете = 2.

having cnt > 2 был бы семантически эквивалентен значению "имеет наименьшее значение 2".

1

Вот моя последняя попытка: :)

select things.* from things 
inner join thing_tags a on a.thingid = things.id and a.tag_id = 6 
inner join thing_tags b on b.thingid = things.id and b.tag_id = 12 
+0

я попробовал подобное решение до публикации этого вопроса, и MySQL возвратил ошибку о том, что «LIMIT & AND/OR/IN с подзапросами не поддерживается эта версия MySQL ». AFAIK Я использую последнюю версию. – SeinopSys

+0

@ DJDavid98 спасибо, что ответили. Я обновил свой ответ с помощью другого варианта. Пожалуйста, дайте мне знать, если это работает. – Akshay

+0

Вы используете 'IN' с подзапросом в обоих решениях. Мой сервер MySQL этого не позволяет. – SeinopSys

Смежные вопросы