2015-09-12 2 views
0

Я хочу запросить это заявление:переписывания SQL-запрос без использования Intersect оператора

Bars that are frequented by both Mike and John 

[таблица часто посещает состоит из 2-х колонок: поилки и бары, они идут к]

Первоначально я думал об использовании этот SQL-запрос с использованием оператора пересечения:

SELECT bar 
FROM frequents 
WHERE drinker ='Mike' 
INTERSECT 
SELECT bar 
FROM frequents 
WHERE drinker ='John' 

, но MySQL не поддерживает использование оператора Intersect. Хотя я могу использовать оператор Join, но мне сложно переписать этот запрос.

ответ

3

Это inner join вы хотите:

SELECT a.bar 
FROM frequents a 
JOIN frequents b ON a.bar = b.bar 
WHERE a.drinker = 'Mike' 
    AND b.drinker = 'John'; 

Обратите внимание, что пересекает сравнивает все столбцы в списке выбора, так что эквивалентно присоединиться к потребностям, чтобы сделать то же самое. В вашем случае это всего лишь один столбец.

Оператор intersect на самом деле не переводить непосредственно в inner join, хотя, как intersect возвращает строки, которые являются общими для наборов по сравнению, в то время как фильтры соединения на заданных условиях и создает новый набор строк, которые состоят из строк в соединенных множествах. Существуют также различия в том, как обрабатываются значения null (и дубликаты).

Другим вариантом было бы использовать exists предикат коррелированных подзапросов:

SELECT a.bar 
FROM frequents a 
WHERE a.drinker ='Mike' 
    AND EXISTS (
    SELECT 1 FROM frequents b 
    WHERE a.bar = b.bar 
     AND b.drinker ='John' 
    ); 

или in предиката:

SELECT bar 
FROM frequents 
WHERE drinker ='Mike' 
AND bar IN (SELECT bar FROM frequents WHERE drinker ='John') 

Есть много других способов сделать это, но я думаю, что я здесь остановимся :)

0

Простым способом для этого является использование агрегации:

select f.bar 
from frequents f 
group by f.bar 
having max(drinker = 'John') > 0 and 
     max(drinker = 'Mike) > 0; 

Или:

select f.bar 
from frequents f 
where f.drinker in ('John', 'Mike') 
group by f.bar 
having count(*) = 2; 

мне нравится пункт having, потому что я считаю его гибким для широкого диапазона условий, таких, как Джон и Майк, но не Сара. Или три Джона, Майка, Сары и Абигейл.