Можете ли вы решить этот простой запрос SQL?
Предположим, это веб-сайт, который продает фотоаппараты. Вот мои сущности (таблицы):
Camera: A simple camera
Feature: A feature like: 6mp, max resolution 1024x768,
Дело в том, что между камерами и функцией у меня есть отношение ко многим, поэтому у меня есть дополнительная таблица:
camera -> cameras_features -> feature
Итак, запрос прост:
Как получить все камеры, которые имеют функцию 1,2 и 3?
Это похоже на создание индекса растрового изображения.
Данные, которые вы можете использовать для проверки правильности решения
C1 has features 1,2,3
C2 has features 1,2,4
C3 has features 1,2
Вот запросы и ожидаемый результат:
- Показать все камеры, которые имеют функции 1,2 и 3: C1
- Показать все камеры, которые имеют функции 1,2 и 4: C2
- Показать все камеры, которые имеют функции 1 и 2: C1, C2 и C3
Вот что я сделал (это работает, но действительно ужасно, я не хочу его использовать):
SELECT * FROM camera c
WHERE c.id IN (
(SELECT c.id FROM camera c JOIN cameras_features f ON (c.id=f.camera_id)
WHERE f.feature_id=1)
q1 JOIN -- simple intersect
(SELECT c.id FROM camera c JOIN cameras_features f ON (c.id=f.camera_id)
WHERE f.feature_id=2)
q2 JOIN ON (q1.id=q2.id)
)
3 ответа
SELECT DISTINCT Camera.*
FROM Camera c
INNER JOIN cameras_features fc1 ON c.id = fc1.camera_id AND fc1.feature_id = 1
INNER JOIN cameras_features fc2 ON c.id = fc2.camera_id AND fc2.feature_id = 2
Здесь происходит то, что камеры будут отфильтрованы до камер с функцией 1, а затем в этой группе камеры будут отфильтрованы до камер с функцией 2
SELECT camera.id
FROM camera JOIN camera_features ON camera.id=camera_features.camera_id
GROUP BY camera.id
HAVING sum(camera_features.feature_id IN (1,2,3))=3
3
это количество функций в (1,2,3)
, И предполагая (camera_id,feature_id)
уникален в camera_features
,
Это проще всего обобщить, поместив значения поиска в таблицу...
INSERT INTO search SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
SELECT
camera_features.camera_id
FROM
camera_features
INNER JOIN
search
ON search.id = camera_features.feature_id
GROUP BY
camera_features.camera_id
HAVING
COUNT(DISTINCT camera_features.feature_id) = (SELECT COUNT(DISTINCT id) FROM search)