MySQL ПОДСЧИТЫВАЕТ результаты инструкции UNION ALL

#mysql #select #union

#mysql #выберите #объединение

Вопрос:

Я уверен, что должен быть способ сделать это, но мои знания MySQL сдерживают меня.

У меня есть единственная таблица, в которой хранятся теги страницы

 page_id          tag
51               New Zealand
51               Trekking
58               UK
77               New Zealand
77               Trekking
89               City Break
101              Shopping
...
  

Я хочу выполнить поиск по страницам, имеющим два тега, например «Новая Зеландия» и «Треккинг». Я просмотрел ОБЪЕДИНЕНИЯ, INTERSECT (equiv), JOINS и я не могу понять, каков наилучший способ сделать это. Лучшее, что я придумал, это сделать:

 SELECT page_id FROM tags
WHERE tag = "New Zealand"
UNION ALL
SELECT page_id FROM tags
WHERE tag = "Trekking"
... and then some kind of COUNT on those pages that feature twice??
  

По сути, я хочу ОБЪЕДИНИТЬ два поиска вместе и «сохранить» дубликаты, а остальные отбросить. Возможно ли это простым способом или мне нужно начать усложнять с этим?

Ответ №1:

Если я вас правильно понял, это должно сработать:

 SELECT page_id, count(*)
FROM tags
WHERE tag IN ('New Zealand', 'Trekking')
GROUP BY page_id
HAVING count(*) > 1
  

Вам не нужно использовать ОБЪЕДИНЕНИЕ, если вы выбираете из той же таблицы.

Комментарии:

1. Идеальный. Большое вам спасибо. «Легко, когда знаешь как».

Ответ №2:

Учитывая, что вам нужен page_id с тегом «Новая Зеландия» и «Поход»

 
SELECT t1.page_id
FROM tags t1, tags t2
WHERE t1.page_id = t2.page_id
AND
t1.tag="New Zealand"
AND
t2.tag="Trekking"

  

Кажется правильным, хм, но проверьте один раз …, будет ли ответный запрос, если я нашел более простой и точный

Ответ №3:

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

 CREATE TABLE temporary
SELECT page_id FROM tags
WHERE tag = "New Zealand"
UNION ALL
SELECT page_id FROM tags
WHERE tag = "Trekking"
  

затем попробуйте это

 SELECT COUNT(*) FROM temporary
  

не забудьте

 DROP TABLE temporary
  

Комментарии:

1. В mysql существует СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ… но это можно легко сделать с помощью вложенного запроса…

2. Хотя этот подход немного слишком сложный, вы могли бы, по крайней мере, использовать CREATE TEMPORARY TABLE temporary_table ... вместо создания жесткой таблицы. Тогда вам не нужно DROP этого делать в конце. Однако на вопрос можно ответить без промежуточной таблицы.