Select 结果中的几行 table 并实现以下输出

Select few rows from a result table and achieve below output

我有两个 table T1

 Boss     employee  
 Bran     josh 
 Bran     paul
 Bran     i-sara
 Bran     shaun
Joseph    will
Joseph    i-alex
Joseph    i-vicky
Joseph    mary
Joseph    cristi

T2

Worker    object       price
josh      bus          2
paul      car          5
i-sara    i-sara       null
Shaun     skate        3
will      football     2
i-alex    i-alex       null
mary      dino         6        
i-vicky   i-vicky      null
Cristi    bike         5

我需要加入两个 table 并获得如下所述的输出 table

所以我写了如下查询

select 老板、员工、对象、T1 的价格左加入 T1.employee=T2.worker 老板的订单;

通过执行上述查询,我​​得到了以下输出

输出:

Boss     employee    object    price
Bran      josh        bus       2
Bran      paul        car       5
Bran      i-sara      i-sara    null
Bran      shaun       skate     3
Joseph    will        football  2
Joseph    i-alex      i-alex    null
Joseph    mary        dino      6
Joseph    i-vicky    i-vicky    null
Joseph    cristi      bike      5

我想从上面的输出 table 中删除员工或对象为“i-%”的行,这是我在执行查询后得到的,并将它们与他们的“老板”放在单独的列中“ 团体。并获得如下输出 table

Boss     employee  object    price  person
Bran      josh      bus       2    i-sara
Bran      paul      car       5    null
Bran      shaun     skate     3    null
Joseph    will      football  2    i-alex, i-vicky
Joseph    mary      dino      6    null
Joseph    cristi    bike      5    null

Boss     employee  object    price  person
Bran      josh      bus       2    i-sara
Bran      paul      car       5    null
Bran      shaun     skate     3    null
Joseph    will      football  2    i-alex
Joseph    mary      dino      6    i-vicky
Joseph    cristi    bike      5    null

任何人都可以帮助我实现我想要的输出吗?

我的做法是在 i-% 案例中单独使用 listagg

select boss, employee, object, price
      ,case when rn = 1 then 
         (select listagg(t2i.worker,',') within group (order by t2i.worker)
            from t2 t2i
            join t1 t1i 
              on t1i.employee = t2i.worker
             and t1i.boss = t1.boss
           where t2i.worker like 'i-%'
          group by t1i.boss
         ) 
       end persons
from
(select boss, employee, object, price,
   row_number() over (partition by t1.boss order by null) rn
  from t1 
left join t2
  on t1.employee = t2.worker
where t1.employee not like 'i-%'
) t1
order by boss;

Db<>fiddle供参考

另一种变体:

with joined as (
   select
      boss, 
      employee, 
      object, 
      price,
      case when employee like 'i-%' then 1 else 0 end grp,
      row_number()over(partition by boss, case when employee like 'i-%' then 1 else 0 end order by employee) rn
   from T1 
        left join T2
             on T1.employee=T2.worker 
)
select
  j1.*, j2.employee as person
from joined j1
     left join joined j2
          on  j1.rn   = j2.rn 
          and j1.boss = j2.boss 
          and j2.grp=1
where j1.grp=0
order by 1,2,3;

如您所见,起初我创建了 CTE joined 并在其中放置了您的原始连接并添加了几列:grp - 0 用于普通行,1 用于 'i-' 行,第二列是 rn - row_number 由老板和 grp 分区并由员工排序 - 您可以在最终结果中看到它作为 rn 列。所以我们可以使用bossrn来加入不同的组。

带有示例数据的完整测试用例:

with t1( Boss,employee  ) as (
select 'Bran'  , 'josh'      from dual union all
select 'Bran'  , 'paul'      from dual union all
select 'Bran'  , 'i-sara'    from dual union all
select 'Bran'  , 'shaun'     from dual union all
select 'Joseph', 'will'      from dual union all
select 'Joseph', 'i-alex'    from dual union all
select 'Joseph', 'i-vicky'   from dual union all
select 'Joseph', 'mary'      from dual union all
select 'Joseph', 'cristi'    from dual
),t2(Worker,object,price) as (
select 'josh'   ,   'bus'     , 2    from dual union all
select 'paul'   ,   'car'     , 5    from dual union all
select 'i-sara' ,   'i-sara'  , null from dual union all
select 'shaun'  ,   'skate'   , 3    from dual union all
select 'will'   ,   'football', 2    from dual union all
select 'i-alex' ,   'i-alex'  , null from dual union all
select 'mary'   ,   'dino'    , 6    from dual union all    
select 'i-vicky',   'i-vicky' , null from dual union all
select 'cristi' ,   'bike'    , 5    from dual
)
,joined as (
   select
      boss, 
      employee, 
      object, 
      price,
      case when employee like 'i-%' then 1 else 0 end grp,
      row_number()over(partition by boss, case when employee like 'i-%' then 1 else 0 end order by employee) rn
   from T1 
        left join T2
             on T1.employee=T2.worker 
)
select
  j1.*, j2.employee as person
from joined j1
     left join joined j2
          on  j1.rn   = j2.rn 
          and j1.boss = j2.boss 
          and j2.grp=1
where j1.grp=0
order by 1,2,3;

结果:

BOSS   EMPLOYE OBJECT        PRICE        GRP         RN PERSON
------ ------- -------- ---------- ---------- ---------- -------
Bran   josh    bus               2          0          1 i-sara
Bran   paul    car               5          0          2
Bran   shaun   skate             3          0          3
Joseph cristi  bike              5          0          1 i-alex
Joseph mary    dino              6          0          2 i-vicky
Joseph will    football          2          0          3

6 rows selected.