Я пытаюсь построить оператор SQL для поиска в двух таблицах, которые находятся в отношении «многие ко многим». Проблема: оператор SQL для поиска продуктов с точными камнями. Например, в таблицах ниже ...

sql
1
Bits Please 18 Янв 2021 в 05:36

1 ответ

Лучший ответ

Это вопрос о реляционном подразделении. Нам нужно найти перекрестное соединение двух таблиц, "разделенных" нашим списком, без остатка, т.е. без других stone в product.

Предположим, что p_id и s_id уникальны:

;WITH StonesToFind AS (    -- we could also use a table variable etc here
    SELECT *
    FROM stone
    WHERE s_name IN ('Ruby','Emerald')
)
SELECT p.p_name
FROM product AS p    -- let's get all products...
JOIN product_stone AS ps ON ps.p_id = p.p_id   -- ...cross join all their stones
LEFT JOIN StonesToFind AS s ON s.s_id = ps.s_id    -- they may have stones in the list
GROUP BY p.p_id, p_name
HAVING COUNT(CASE WHEN s.s_id IS NULL THEN 1 END) = 0
-- the number of non matching stones in product must be zero
    AND COUNT(*) = (SELECT COUNT(*) FROM StonesToFind);
-- the total number of stones must be the same as the list
1
Charlieface 18 Янв 2021 в 03:15