简体   繁体   English

Oracle SQL 查询根据值排除一组记录

[英]Oracle SQL query to exclue a set of records based on values

My post title might be awkward, but let me try to explain what I am trying to achieve with an oracle sql query.我的帖子标题可能很尴尬,但让我试着解释一下我想用 oracle sql 查询来实现什么。

My table is as below.我的表如下。

Requirement is, when the seqNo is shared by "apple", then I Do Not want the record to be selected.要求是,当 seqNo 被“apple”共享时,我希望该记录被选中。

Only if Apple alone is having a sequence number(Not shared by any other Category), only then select the record, as shown in the below table.仅当 Apple 单独具有序列号(不与任何其他类别共享)时,才 select 记录,如下表所示。

Any help is highly appreciated.非常感谢任何帮助。

I tried to partion based on seqNo, and ranking it on category, but since the category is string, I could not achieve it.我尝试根据seqNo进行partion,并按category排序,但是由于category是string,我无法实现。

|SeqNo   |   Category|
|------ |---------|
|1    |   Banana|
|3    |   Apple ---> *do not select as sequence number is shared*|
|3    |   Orange ---> *do not select as sequence number is shared*|
|4    |   Mango|
|4    |   Banana|
|7    |   Orange---> *do not select as sequence number is shared*|
|7    |   Apple---> *do not select as sequence number is shared*|
|7    |   Mango---> *do not select as sequence number is shared*|
|9    |   Apple-->**Only Select this**|
|11   |   Banana|
|13   |   Mango|
|14   |   Apple-->**Only Select this**|
|18   |   Apple-->**Only Select this**|
|42   |   Mango|

Schema:架构:

 create table mytable (SeqNo int,   Category varchar(505));
 insert into mytable values(1    ,'Banana');
 insert into mytable values(3    ,'Apple');
 insert into mytable values(3    ,'Orange');
 insert into mytable values(4    ,'Mango');
 insert into mytable values(4    ,'Banana');
 insert into mytable values(7    ,'Orange');
 insert into mytable values(7    ,'Apple');
 insert into mytable values(7    ,'Mango');
 insert into mytable values(9    ,'Apple');
 insert into mytable values(11   ,'Banana');
 insert into mytable values(13   ,'Mango');
 insert into mytable values(14   ,'Apple');
 insert into mytable values(18   ,'Apple');
 insert into mytable values(42   ,'Mango');

Query#1 (to find rows for seqno with single record and which is 'Apple')查询#1(查找 seqno 的单记录行,即“Apple”)

  with cte as ( select seqno,category,count(*)over(partition by seqno ) cnt from mytable )
  select * from cte where cnt=1 and trim(category)='Apple'

Output: Output:

seqno序列号 category类别 cnt cnt
9 9 Apple苹果 1 1
14 14 Apple苹果 1 1
18 18 Apple苹果 1 1

Query#2 (to remove the rows which have multiple rows for a sequence number and one have category 'Apple')查询#2(删除具有多行序列号且一个具有类别“Apple”的行)

     with cte as 
     (
         select seqno,category,count(*)over(partition by seqno ) cnt from mytable
     )
     select * from mytable 
     where not exists
                    (
                     select * from cte where cnt=2 and trim(Category)='Apple' and 
                     mytable.seqno=cte.seqno
                    );

Output: Output:

SeqNo序列号 Category类别
1 1 Banana香蕉
4 4 Mango芒果
4 4 Banana香蕉
9 9 Apple苹果
11 11 Banana香蕉
13 13 Mango芒果
14 14 Apple苹果
18 18 Apple苹果
42 42 Mango芒果

db<fiddle here db<小提琴在这里

I would use window functions to count the number of apples and total rows for a seq_no and then use filtering logic:我会使用 window 函数来计算seq_no的苹果数和总行数,然后使用过滤逻辑:

select t.*
from (select t.*,
             count(*) over (partition by seq_no) as cnt,
             sum(case when category = 'Apple' then 1 else 0 end) over (partition by seq_no) as num_apple
      from t
     ) t
where num_apple = 0 or
      (num_apple = cnt and num_apple = 1);

The last condition is the one that is ambiguous in the question.最后一个条件是问题中模棱两可的条件。 If there are exactly two apples for the seq_no , I don't know if it should be returned or not.如果seq_no正好有两个苹果,我不知道它是否应该被退回。 If you want such cases, then remove the num_apple = 1 .如果您想要这种情况,请删除num_apple = 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM