oracle的

时间:2017-10-17 11:23:31

标签: oracle

我有一个场景,我需要获取一个来源的ID中的所有记录以及其他来源。以下是我输入的记录集。

ID  SOURCE  CURR_FLAG       TYPE
1   IBM       Y               P
1   IBM       Y               OF
1   IBM       Y               P
2   IBM       Y               P
2   TCS       Y               P
3   IBM     NULL              P
3   CTS     NULL              P
3   TCS     NULL              P
4   IBM     NULL              OF
4   CTS     NULL              OF
4   TCS      Y                ON
5   CTS     NULL              OF
5   TCS      Y                ON

从上面的记录中,我需要在同一个ID组中选择源为IBM的所有记录,其他来源也应该与IBM一起使用相同的ID。另外,我们只需要获取那些记录的记录。使用curr_fl =' Y'

在该ID组中至少有一条记录

在上面的场景中,即使ID = 1有一个源为IBM,但该特定组中没有其他源的记录。所以我们不应该使用该ID获取该记录。 对于记录ID = 3有一个源作为IBM以及其他来源,但没有记录与CURR_FL =' Y',我的查询不应该获取值。在ID = 4的情况下,它可以获取ID = 4的所有记录,因为其中一个记录具有值=' Y'它有IBM与其他源的组合。对于ID 5它不应该获取,因为我们在该集合中没有任何IBM记录源

同样在满足上述条件的组内,我还需要一个类型的条件。如果有类型=' P'的记录,那么我只需要获取该记录。如果没有P的记录,那么我将搜索type =' OF' else type =' ON'

我的预期输出如下:

ID  SOURCE  CURR_FLAG       TYPE
2   IBM       Y               P
2   TCS       Y               P
4   IBM     NULL              OF
4   CTS     NULL              OF
4   TCS      Y                ON

我已经写了一个如下所示的查询。但是它运行了很长时间而没有取得任何结果。有没有更好的方法来修改此查询

select
    ID,
    SOURCE,
    CURR_FL,
   TYPE
from TABLE a where 
  exists(select 1 from TABLE B where a.ID=B.ID and a.rowid<>B.rowid and B.source<>a.source)
  and exists(select 1 from TABLE C where a.ID=C.ID and C.source ='IBM')
and exists(select 1 from TABLE D where a.ID=D.ID and D.CURR_FL='Y') and
(TYPE,ID) IN (
select case  type when 1 then 'P' when 2 then 'OF' else 'ON' END TYPE,ID  from
(select ID,
     max(priority) keep (dense_rank first order by priority asc) as type
      from ( select ID,TYPE,
               case TYPE 
                     when 'P' then 1
                     when 'OF' then 2
                     when 'ON' then 3
                end as priority 
           from TABLE where ID 
            in(select ID from TABLE where CURR_FL='Y') AND SOURCE='IBM' 
                )
                group by ID))

2 个答案:

答案 0 :(得分:0)

首先,查找id s。我建议:

select id
from t
group by id
having min(source) <> max(source) and                            -- at least two sources
       sum(case when curr_flag = 'Y' then 1 else 0 end) > 0 and  -- at least one Y
       sum(case when source = 'IBM' then 1 else 0 end) > 0       -- IBM

要获取基本行,您可以使用inexistsjoin

select t.*
from t
where id in (select id
             from t
             group by id
             having min(source) <> max(source) and                            -- at least two sources
                    sum(case when curr_flag = 'Y' then 1 else 0 end) > 0 and  -- at least one Y
                    sum(case when source = 'IBM' then 1 else 0 end) > 0       -- IBM
            );

答案 1 :(得分:0)

使用分析函数,您可以检查组中是否至少有一个IBM,组中至少有一个除IBM之外的其他源,以及组中至少有一个带Y的标志:

with t(id, source, curr_flag, type) as
(
  select 1, 'IBM', 'Y', 'P' from dual union all
  select 1, 'IBM', 'Y', 'OF' from dual union all
  select 1, 'IBM', 'Y', 'P' from dual union all
  select 2, 'IBM', 'Y', 'P' from dual union all
  select 2, 'TCS', 'Y', 'P' from dual union all
  select 3, 'IBM', NULL, 'P' from dual union all
  select 3, 'CTS', NULL, 'P' from dual union all
  select 3, 'TCS', NULL, 'P' from dual union all
  select 4, 'IBM', NULL, 'OF' from dual union all
  select 4, 'CTS', NULL, 'OF' from dual union all
  select 4, 'TCS', 'Y', 'ON' from dual union all
  select 5, 'CTS', NULL, 'OF' from dual union all
  select 5, 'TCS', 'Y', 'ON' from dual
)
select id, source, curr_flag, type
  from (select id, source, curr_flag, type,
               max(case when source = 'IBM' then 1 end) over (partition by id) ibm,
               max(case when source != 'IBM' then 1 end) over (partition by id) not_ibm,
               max(case when curr_flag = 'Y' then 1 end) over (partition by id) flag_y
          from t)
 where ibm = 1
   and not_ibm = 1
   and flag_y = 1
 order by id, source;