Я не знаю, почему вы используете CROSS JOIN
. Это обычно для создания декартовых продуктов. Все, что вам нужно, это просто INNER JOIN
или просто JOIN
.
Я обычно использую OUTER JOIN
, когда хочу проверить отсутствие некоторых данных. Если совпадений не найдено, t5
будет НЕДЕЙСТВИТЕЛЕН.
SELECT t1.id, col
FROM extra as e
INNER JOIN your_table as t1 ON ( e.id=t1.id AND t1.color = 'blue' )
INNER JOIN your_table as t2 ON ( e.id=t2.id AND t2.color = 'purple' )
INNER JOIN your_table as t3 ON ( e.id=t3.id AND t3.color = 'green' )
INNER JOIN your_table as t4 ON ( e.id=t4.id AND t4.color = 'white' )
LEFT OUTER JOIN your_table as t5 ON ( e.id=t5.id AND t5.color = 'black' )
WHERE t5.id IS NULL;
Вы правы, что вышеуказанная техника с использованием объединений быстрее, чем с помощью коррелированных подзапросов, и также (по крайней мере, в MySQL) быстрее, чем решение GROUP BY
, которое используют некоторые люди:
SELECT e.id, col
FROM extra as e
INNER JOIN your_table AS t USING ( id)
WHERE t.color IN ('blue', 'purple', 'green', 'white')
GROUP BY e.id
HAVING COUNT(*) = 4;
(Этот запрос не решает проблему «не черных», я просто иллюстрирую технику.)