SQL匹配,如果不是0或> 4

时间:2018-05-25 10:19:49

标签: sql oracle

这是我的问题。

我有4个表作为示例(Shape - > ShapeDetails - > ShapeSize - > ShapeColor)

基本上每次创建一个新的Shape时都会创建一个新的ShapeColor线(并且我选择的每种颜色都在表ShapeColor中创建了新的线)我不方便,但我必须使用的软件设计如下。< / p>

所以,一个Shape可以有很多颜色,但我想基于颜色的“名称”匹配那些颜色为“红色”,“粉红色”,“蓝色”但是如果其中一个有“在这种情况下,红色“,”粉红色“,”蓝色“和”黄色“不应匹配。

我想匹配1和/或3种颜色之间的颜色。 示例(颜色:红色,粉红色,蓝色,黄色):

  • 0 0 0 0(这些颜色中没有一个= NOK)不在resulstSet中
  • 1 0 0 0(仅红色但不是粉红色蓝色黄色= OK)在resultSet中匹配
  • 0 1 0 0(仅粉红色但不是红蓝黄= OK)匹配
  • 1 1 0 0(只有红色粉红色但不是蓝色和黄色= OK)匹配
  • 1 0 1 0 ...
  • 1 1 1 1(所有这些颜色= NOK)不在resultsSet
不过,我使用一些连接来获取ShapeColor

我不知道如何用一个SQL查询解决这个问题,任何一种帮助都将非常感激

3 个答案:

答案 0 :(得分: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' 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

答案 1 :(得分:0)

假设颜色是独立的,您可以这样做:

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

答案 2 :(得分:0)

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