如何省略属性基于2个不同字段的“like”子句的记录组

时间:2017-02-02 17:00:36

标签: sql database oracle

我需要一个查询来省略两个记录中存在数字16的组,并且这些组存在于组内的不同属性中。基本上,如果我们在不同记录的属性中有一个16,那么我们知道这些组的帐户是什么,并且不需要对它们进行进一步的分析。我们希望保留结果,其中16只出现在任一属性中的一个记录中,16出现在两者中,并且记录中包含空值但没有16个记录在不同属性中。

以下是一个例子:

---------------------------------------------
| groupid    | category     |  test_results |
---------------------------------------------
| 001        |  red13tall   |               |
| 001        |              |  blue16small  |
| 002        |  green16small|               |
| 002        |              |  blue16small  |
| 003        |  yellow3tall |               |   
| 003        |              |  green2giant  |
| 004        | orange16tall |               |
| 004        |              |  blue16tall   |
| 005        | red16short   |               |
| 005        | green12bald  |  orange14tall |
| 006        | blue3short   |  red16big     |
| 006        | green16flat  |               |
--------------------------------------------- 

这是我们正在寻找的结果:

---------------------------------------------
| groupid    | category     |  test_results |
---------------------------------------------
| 001        |  red13tall   |               |
| 001        |              |  blue16small  |
| 003        |  yellow3tall |               |   
| 003        |              |  green2giant  |
| 005        | red16short   |               |
| 005        | green12bald  |  orange14tall |
 ------------------------------------------ 

2 个答案:

答案 0 :(得分:1)

假设您的表名为your_table且主键为id,那么

SELECT t3.groupid, t3.category, t3.test_results
FROM your_table t3
WHERE t3.groupid NOT IN (
  SELECT t1.groupid
  FROM your_table t1, your_table t2
  WHERE t1.id <> t2.id
  AND t1.groupid = t2.groupid
  AND t1.category LIKE '%16%'
  AND t2.test_results LIKE '%16%'
)

注意,这假设您正在寻找16出现在2个不同列中的两个不同行中。如果您不在乎它们是否出现在同一行中,则可以删除t1.id <> t2.id条件。

答案 1 :(得分:1)

您需要以某种方式进行条件计数。如果使用分析函数,则可以避免连接,这通常会影响性能。

对于下面的解决方案,我按字面解释了你的单词:每组只有两行,如果满足所有三个条件,则排除一组:两行至少有16行(category或{{} 1}}); 16 test_results出现至少一次;和{16}出现在category至少一次。

如果您不需要至少有一次16的组的每一行上的条件,则可以非常轻松地修改查询(删除对test_results的所有引用)。

r_ct

<强>输出

with
     test_data ( groupid, category, test_results ) as (
       select '001', 'red13tall'   , null           from dual union all
       select '001', null          , 'blue16small'  from dual union all
       select '002', 'green16small', null           from dual union all
       select '002', null          , 'blue16small'  from dual union all
       select '003', 'yellow3tall' , null           from dual union all
       select '003', null          , 'green2giant'  from dual union all
       select '004', 'orange16tall', null           from dual union all
       select '004', null          , 'blue16tall'   from dual union all
       select '005', 'red16short'  , null           from dual union all
       select '005', 'green12bald' , 'orange14tall' from dual union all
       select '006', 'blue3short'  , 'red16big'     from dual union all
       select '006', 'green16flat' , null           from dual
     )
--  end of test data (not part of solution); SQL query begins below this line
select   groupid, category, test_results
from     (
           select groupid, category, test_results,
                  count(case when category     like '%16%' then 1 
                             when test_results like '%16%' then 1 end) 
                             over (partition by groupid)               as r_ct,
                  count(case when category     like '%16%' then 1 end) 
                             over (partition by groupid)               as c_ct,
                  count(case when test_results like '%16%' then 1 end) 
                             over (partition by groupid)               as t_ct
           from   test_data
         )
where    r_ct < 2 or c_ct = 0 or t_ct = 0
order by groupid   --  if needed
;