如果您发现使用 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;