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
列。所以我们可以使用boss
和rn
来加入不同的组。
带有示例数据的完整测试用例:
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.
我有两个 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
列。所以我们可以使用boss
和rn
来加入不同的组。
带有示例数据的完整测试用例:
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.