2016-10-07 2 views
0

Я пытаюсь пересечь эти запросы. Я собираюсь иметь от двух пересекающихся запросов до пяти пересекающихся запросов.Как пересечь несколько запросов с помощью MYSQL?

select * from Main 
left join title_keyword_link on Main.id = title_keyword_link.title_id 
left join keywords_master on title_keyword_link.keyword_id = keywords_master.id 
where keywords_master.keyword = 'opinion' 

INTERSECT 

select * from Main 
left join title_keyword_link on Main.id = title_keyword_link.title_id 
left join keywords_master on title_keyword_link.keyword_id = keywords_master.id 
where keywords_master.keyword = 'sports' 

я узнал, что MYSQL не поддерживает INTERSECT, поэтому я попробовал некоторые из предложенных альтернатив. Я пробовал:

select * from Main 
left join title_keyword_link on Main.id = title_keyword_link.title_id 
left join keywords_master on title_keyword_link.keyword_id = keywords_master.id 
where keywords_master.keyword in ('opinion', 'sports') 

^Это показывает результаты, которые больше похожи на UNION мнений и спорта

Я также попытался:

select keywords from Main 
left join title_keyword_link on Main.id = title_keyword_link.title_id 
left join keywords_master on title_keyword_link.keyword_id = keywords_master.id 
where keywords_master.keyword = 'sports' 
and keywords_master.keyword in (select keywords from Main 
    left join title_keyword_link on Main.id = title_keyword_link.title_id 
    left join keywords_master on title_keyword_link.keyword_id = keywords_master.id 
    where keywords_master.keyword = 'opinion') 

^Этот код вызывает MySQL Workbench к сбою.

ответ

1

Чтобы получить строки из Main, которые связаны с ключевыми словами, «мнение» и «спорт», я хотел бы использовать запрос, как это :

SELECT m.* 
    FROM Main m 
    JOIN (SELECT k.title_id 
      FROM title_keyword_link k 
      JOIN keywords_master r 
       ON r.id = k.keyword_id 
      WHERE r.keyword IN ('opinion','sports') -- specific keywords to search for 
      GROUP BY k.title_id 
      HAVING COUNT(DISTINCT r.keyword) = 2  -- number of keywords to match 
     ) s 
     ON s.title_id = m.id       -- only return rows that match 

Эквивалентный результат может быть получен с помощью "EXISTS (correlated subquery)" узор:

SELECT m.* 
    FROM Main m 
    WHERE EXISTS (SELECT 1 
        FROM title_keyword_link k1 
        JOIN keywords_master r1 
         ON r1.id = k1.keyword_id 
        WHERE r1.keyword = 'opinion' -- keyword 1 to search for 
        AND k1.title_id = m.id  -- matches row in outer query 
       ) 
    AND EXISTS (SELECT 1 
        FROM title_keyword_link k2 
        JOIN keywords_master r2 
         ON r2.id = k2.keyword_id 
        WHERE r2.keyword = 'sports' -- keyword 2 to search for 
        AND k2.title_id = m.id  -- matches row in outer query 
       ) 

Эти примерные запросы возвращают набор результатов, все строки в Main, которые связаны как с ключевыми словами «мнение», так и «спорт».

Но ни один из этих двух примеров запросов отвечает на вопрос, который был задан вопрос:


Q: «Как пересекаются несколько запросов»

A: Можно получить «пересечение» результатов, возвращаемых двумя (или более) запросами в MySQL. В некоторых случаях мы можем эмулировать отсутствующий оператор набора INTERSECT, используя операцию INNER JOIN для встроенных представлений.

Для конкретного запроса, как показано в этом вопросе, это не можно использовать этот точный запрос как вложенное представление, поскольку запрос возвращает несколько столбцов с тем же именем. (Корень проблемы - это select *, а таблица Main и таблица keywords_master содержат столбец с именем id. Запрос нужно будет изменить так, чтобы он возвращал только разные имена столбцов.)

Мы также отмечаем, что в запросе OP «наивность» операций LEFT JOIN сбрасывается предикатом в предложении WHERE. Результат, полученный из этого запроса, будет эквивалентен результатам, возвращаемым с использованием операций внутреннего соединения.

+0

Спасибо! Этот ответ будет ценным, поскольку я пересекаю больше ключевых слов. И быстрее! – Sedrick

+1

Для нетривиальных множеств с подходящими индексами, доступными для таблиц, оба запроса должны быть * намного быстрее, чем операция объединения на две (или более) производные таблицы. Кроме того, если это были мои запросы, я бы заменил «SELECT m. *» На список конкретных выражений, которые будут возвращены ... например. 'SELECT m.id, m.title, LEFT (m.foo, 40) AS foo FROM'. – spencer7593

-3

Пересекая, вы имеете в виду декартово произведение?

Где вы хотите пересечь таблицы?

Я думаю о LEFT JOIN, но вам, возможно, придется объединить LEFT JOIN с другими объявлениями.

Можете ли вы выполнять подзапросы? Возможно, вам придется комбинировать подзапросы с LEFT JOIN.

+0

Это не ответ. Зарабатывайте репутацию и комментируйте где угодно. Ответы не для болтовни – Drew

+0

Не много опыта работы с SQL, но когда я говорю, пересекаюсь, я имею в виду разные запросы и сохраняю результат, который соответствует. Пример набора A Набор пересечений B. A = [1, 2, 3, 4]. B = [2, 4, 5]. A пересечение B = [2, 4]. – Sedrick

1

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

select * from (

select Main.id from Main 
left join title_keyword_link on Main.id = title_keyword_link.title_id 
left join keywords_master on title_keyword_link.keyword_id = keywords_master.id 
where keywords_master.keyword = 'opinion' 

) t1 
inner join (
    select Main.id from Main 
    left join title_keyword_link on Main.id = title_keyword_link.title_id 
    left join keywords_master on title_keyword_link.keyword_id = keywords_master.id 
    where keywords_master.keyword = 'sports' 
) t2 on t1.id = t2.id 
+0

Запрос (как показано, с 'select *' в запросах inline view) скорее всего вызовет ошибку 1060, так как таблица 'Main' и таблица' keywords_master' содержат столбец с именем 'id'. – spencer7593

+0

Он сделал ошибку 1060, но я работаю над этим. – Sedrick

+0

Обновление не было моим окончательным ответом, но это привело меня к моему окончательному ответу. Благодаря! – Sedrick

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