Как проверить точное совпадение в таблице соединений - PullRequest
0 голосов
/ 14 февраля 2019

Рассмотрим следующую проблему:

  • Таблица «Рисунок» с идентификатором, заголовком, размером.
  • Таблица «Цвет» с идентификатором, меткой.
  • Таблица соединений 'Pic_Col' с picture_id, color_id
  • Каждое изображение имеет от 1 до n цветов

Я пытаюсь найти в SQL (DB2, но мне любопытно, что касается других СУБДвозможности) способ вернуть что-то, что ответило бы на следующие вопросы:

  • Один запрос для:

    Содержит ли изображение с идентификатором X только синий и желтый цвета?

  • Один запрос для:

    Содержит ли изображение с идентификатором Y хотя бы синий и желтый цвета?

    Содержит ли изображение с идентификатором Zнаименее синий и желтый, но без красного?

Я хотел бы предоставить в качестве параметров: идентификатор изображения, список желаемых цветов, список нежелательных цветов.

Единственные решения, которые мне удалось найти, основаны на EXISTS с подзапросами или X объединениями (X - это номер цвета iв запросе) и агрегация (CASE WHEN и т. д.) ...

    SELECT 1
    FROM 
        picture p
    WHERE
        p.id = 123
        AND EXISTS (
            SELECT 1
            FROM pic_col pc
                INNER JOIN color c ON (c.id = pc.color_id AND c.label = 'blue')
            WHERE
                pc.picture_id = p.id
        )
        AND EXISTS (
            SELECT 1
            FROM pic_col pc
                INNER JOIN color c ON (c.id = pc.color_id AND c.label = 'yellow')
            WHERE
                pc.picture_id = p.id
        )
        AND NOT EXISTS (
            SELECT 1
            FROM pic_col pc
                INNER JOIN color c ON (c.id = pc.color_id AND c.label = 'red')
            WHERE
                pc.picture_id = p.id
        );

1 Ответ

0 голосов
/ 14 февраля 2019

Мне нравится условное агрегирование для этой цели.

Содержит ли изображение с идентификатором X только синий и желтый цвета?

select picture_id
from pic_col pc join
     colors c
     on pc.color_id = c.id
group by picture_id
having count(*) = sum(case when c.label in ('blue', 'yellow')

Имеет ли картинкас идентификатором Y содержит хотя бы синий и желтый?

select picture_id
from pic_col pc join
     colors c
     on pc.color_id = c.id
group by picture_id
having sum(case when c.label = 'blue' then 1 else0 end) > 0 and
       sum(case when c.label = 'yellow' then 1 else 0 end) > 0;

Содержит ли изображение с идентификатором Z хотя бы синий и желтый, но не красный?

select picture_id
from pic_col pc join
     colors c
     on pc.color_id = c.id
group by picture_id
having sum(case when c.label = 'blue' then 1 else0 end) > 0 and
       sum(case when c.label = 'yellow' then 1 else 0 end) > 0 and
       sum(case when c.label = 'red' then 1 else 0 end) =  0;

Предложение having складывает количество совпадений для каждого цвета (или группы цветов) для каждого изображения.> 0 говорит, что цвет присутствует.= 0 говорит, что цвет отсутствует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...