【问题标题】:SQL match if not 0 or > 4如果不是 0 或 > 4,则 SQL 匹配
【发布时间】:2018-05-25 21:51:12
【问题描述】:

这是我的问题。

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

基本上每次我创建一个新形状时,都会创建一个新线 ShapeColor(并且对于我选择的每种颜色都会在表 ShapeColor 中创建新线)我知道不方便,但我必须使用的软件是这样设计的。

所以,一个形状可以有很多颜色,但我想根据颜色的“名称”匹配那些颜色为“红色”、“粉红色”、“蓝色”但如果其中一个有“ red","pink","blue" 和 "yellow" 在这种情况下不应该匹配。

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

  • 0 0 0 0(这些颜色都不是 = NOK)不在结果集中
  • 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)不在结果集中

顺便说一句,我使用一些连接来获得 ShapeColor

我不知道如何用一个 SQL 查询解决这个问题,非常感谢任何形式的帮助

【问题讨论】:

    标签: sql oracle


    【解决方案1】:
    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
    

    【讨论】:

    • 感谢您的解决方案,但在我的情况下,有时黄色可能是颜色的一部分。所以 "red" , "blue" , "yellow" 也应该匹配。问题更像是:如果缺少其中一种颜色(红色、粉色、蓝色、黄色),那么我想匹配形状。你应该有 0 或所有这 4 种颜色,否则结果集中的形状匹配
    【解决方案2】:

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

    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(*) &gt; 0 AND COUNT(*) &lt; 4

    【讨论】:

    • 不确定您是否理解正确。事实上,我可以这样做,但我可以有 4 种以上的颜色,我可以有 15 种作为示例,但我只想匹配那些缺少一组颜色的颜色示例:颜色组(“红色”,“粉红色” ","blue","yellow") 如果一个形状有这 4 种颜色,那么记录不应该匹配,但如果其中一种颜色缺失,那么它应该匹配
    • @NickyL 。 . .这很容易在聚合之前使用where 进行过滤。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-07
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 2011-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多