Соответствие SQL, если не 0 или> 4 - PullRequest
0 голосов
/ 25 мая 2018

Вот моя проблема.

В качестве примера у меня есть 4 таблицы (Shape -> ShapeDetails -> ShapeSize -> ShapeColor)

Обычно каждый раз, когда я создаю новый Shape, появляется новая строкаShapeColor создан (и для каждого выбранного мной цвета создается новая строка в таблице ShapeColor) Неудобно, я знаю, но программное обеспечение, которое я должен использовать, было разработано следующим образом.

Итак, Shape может иметь много цветовно я хотел бы сопоставить на основе "названия" цвета те, которые имеют цвет "красный", "розовый", "синий", НО, если один из них имеет "красный", "розовый", "синий" и "желтый"«в этом случае этот не должен совпадать.

Я хотел бы сопоставить те, которые находятся между 1 и / или 3 цветами.Пример (цвета: красный, розовый, синий, желтый):

  • 0 0 0 0 (ни один из этих цветов = NOK) отсутствует в resulstSet
  • 1 0 0 0 (толькокрасный, но не розовый синий желтый = ОК) Совпадение в результате набора
  • 0 1 0 0 (только розовый, но не красный синий желтый = ОК) Совпадение
  • 1 1 0 0 (только красный розовый, ноне синий и желтый = ОК) Совпадение
  • 1 0 1 0 ...
  • 1 1 1 1 (все эти цвета = NOK) отсутствует в результатахУстановить

Кстати, я использую некоторые объединения, чтобы добраться до ShapeColor

Я не знаю, как решить эту проблему одним SQL-запросом, любая помощь будет очень признательна

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

При условии, что цвета независимы, вы можете сделать:

SELECT sc.shape_id
FROM shape_color sc join
     color c
     ON sc.color_id = c.color_id
WHERE c.color in ('red', 'pink', 'blue', 'yellow')
GROUP BY sc.shape_id
HAVING COUNT(*) < 4;

(Ваши имена столбцов не ясны, но вы должны понять.)

Посмотрев в shape_color, вы устраняете первое условие - нужен цвет.Затем он просто проверяет, что существует менее 4 цветов.Неявно, есть хотя бы один, но вы могли бы добавить HAVING COUNT(*) > 0 AND COUNT(*) < 4.

0 голосов
/ 25 мая 2018

Если вы обнаружите, что решение с GROUP BY и HAVING может привести к путанице, просто сначала объедините цвета в строке, используя LISTAGG.

Обратите внимание, что при использовании INNER JOIN исключаются фигуры без цветов (здесь 4- см. пример данных ниже).

Также предикат WHERE ограничивает только соответствующие цвета.

select s.shape_id,
LISTAGG(c.color, ',') WITHIN GROUP (ORDER BY c.color) color_lst
from shape s
join shape_color c
on s.shape_id = c.shape_id
where c.color in ('red', 'pink', 'blue', 'yellow')
group by s.shape_id
;

  SHAPE_ID COLOR_LST                  
---------- ---------------------------
         1 blue,pink,red,yellow         
         2 red                          
         3 blue,pink,yellow 

Ваша задача настолько же проста, как и исключить единственный отрицательный случай из всех четырех цветов:

with colors as (
select s.shape_id,
LISTAGG(c.color, ',') WITHIN GROUP (ORDER BY c.color) color_lst
from shape s
join shape_color c
on s.shape_id = c.shape_id
where c.color in ('red', 'pink', 'blue', 'yellow')
group by s.shape_id
)
select shape_id
from colors
where color_lst != 'blue,pink,red,yellow'

  SHAPE_ID
----------
         2 
         3

Вы должны позаботиться о том, чтобы убедиться, что цвета внутри фигуры уникальны.Если нет, вы должны добавить подзапрос, который различает цвета в форме. То же самое относится и к решениям HAVING .

Пример данных

create table shape  as
select 1 shape_id from dual union all
select 2 shape_id from dual union all
select 3 shape_id from dual union all
select 4 shape_id from dual;

create table shape_color as
select 1 shape_id, 'red' color from dual union all
select 1 shape_id, 'pink' color from dual union all
select 1 shape_id, 'blue' color from dual union all
select 1 shape_id, 'yellow' color from dual union all
select 2 shape_id, 'red' color from dual union all
select 3 shape_id, 'pink' color from dual union all
select 3 shape_id, 'blue' color from dual union all
select 3 shape_id, 'yellow' color from dual;
0 голосов
/ 25 мая 2018
SELECT s.id
FROM shape s INNER JOIN shape_color sc ON s.id=sc.id
GROUP BY s.id
HAVING 
  SUM(CASE WHEN sc.color='red' OR sc.color='pink' OR sc.color='blue' 1 ELSE 0 END) >0
  AND
  HAVING SUM(CASE WHEN sc.color='yellow' 1 ELSE 0 END) = 0

HAVING применяется к сгруппированным результатам, если сумма допустимых цветов> 0, что означает, что для фигуры существует один из 3 действительных цветов, если сумма недопустимых цветов> 0, что означает желтый цвет

Таким образом, вы получите формы, в которых существует один (или более) из допустимых цветов, а недопустимый цвет не существует

ОБНОВЛЕНИЕ:

SELECT s.id
FROM shape s INNER JOIN shape_color sc ON s.id=sc.id
GROUP BY s.id
HAVING 
  SUM(CASE WHEN sc.color='red' OR sc.color='pink' OR sc.color='blue' OR sc.color='yellow' 1 ELSE 0 END) >0
AND
  SUM(CASE WHEN sc.color='red' OR sc.color='pink' OR sc.color='blue' OR sc.color='yellow' 1 ELSE 0 END) <=3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...