我的查询是:
select A.*
from (select r.role_id,
r.role_name,
r.active,
decode( r.entity_type_id, 1000, m.name, 3000, cour.name, 4000, 'Ensenda' ) companyName,
LISTAGG(p.permission_id, ' | ') WITHIN GROUP (ORDER BY r.role_id) permission_id,
LISTAGG(p.permission_name, ' | ') WITHIN GROUP (ORDER BY r.role_id) permission_name,
row_number() over (order by r.created_ts desc) as RN,
count(*) over () as TOTAL_ROWS,
r.created_ts roleCreated
from t_role r
left join t_role_permission rp ON r.role_id = rp.role_id
left join t_permission p ON rp.permission_id = p.permission_id
left join merchant m on r.entity_id = m.merchantkey
left join courier cour on r.entity_id = cour.courierkey
where 1=1
--and p.permission_id =301446
group by r.role_id, r.role_name, r.active, r.created_ts,
decode( r.entity_type_id, 1000, m.name, 3000, cour.name, 4000, 'Ensenda' )
) A
where RN between 1 and 100 order by roleCreated desc
我的结果是:
现在我想在permission_id
的基础上过滤列表,这样我就可以在permission_id列中找到与该permission_id匹配的所有记录的列表。
例如:假设我为permission_id= 301446
做了一个过滤器。我想要以下结果
PS:在where子句中添加和p.permission_id=301446
将不会产生所需的结果。
答案 0 :(得分:1)
基于PasserBy评论的答案
select A.* from(select r.role_id, r.role_name, r.active,
decode( r.entity_type_id, 1000, m.name, 3000, cour.name, 4000, 'Ensenda' ) companyName,
LISTAGG(p.permission_id, ' | ') WITHIN GROUP (ORDER BY r.role_id) permission_id,
LISTAGG(p.permission_name, ' | ') WITHIN GROUP (ORDER BY r.role_id) permission_name,
row_number() over (order by r.created_ts desc) as RN, count(*) over () as TOTAL_ROWS, r.created_ts roleCreated
from t_role r
left join t_role_permission rp ON r.role_id = rp.role_id
left join t_permission p ON rp.permission_id = p.permission_id
left join merchant m on r.entity_id = m.merchantkey
left join courier cour on r.entity_id = cour.courierkey
where 1=1
group by r.role_id, r.role_name, r.active, r.created_ts,
decode( r.entity_type_id, 1000, m.name, 3000, cour.name, 4000, 'Ensenda' )
)A where RN between 1 and 100
and REGEXP_LIKE(a.permission_id,'(^|\s)301446(\s|$)')
order by roleCreated desc;
答案 1 :(得分:1)
对于你正在寻找的permission_id的值不常见的大型数据集,查询整个数据集然后对聚合结果进行过滤将是非常低效的,并且看起来似乎是逻辑上不正确的结果。 / p>
您要查找的内容不是权限ID列表包含特定值的角色列表,而是包含特定权限的角色的权限ID列表。从逻辑上讲,它最终会起到同样的作用,但是更符合问题的逻辑实现似乎总是带来可读性和(奇怪的)性能优势。
无论如何,我确信你最好过滤掉包含所需权限的角色,然后只为它们运行查询:
select A.*
from (select r.role_id,
r.role_name,
r.active,
decode( r.entity_type_id, 1000, m.name, 3000, cour.name, 4000, 'Ensenda' ) companyName,
LISTAGG(p.permission_id, ' | ') WITHIN GROUP (ORDER BY r.role_id) permission_id,
LISTAGG(p.permission_name, ' | ') WITHIN GROUP (ORDER BY r.role_id) permission_name,
row_number() over (order by r.created_ts desc) as RN,
count(*) over () as TOTAL_ROWS,
r.created_ts roleCreated
from t_role r
left join t_role_permission rp ON r.role_id = rp.role_id
left join t_permission p ON rp.permission_id = p.permission_id
left join merchant m on r.entity_id = m.merchantkey
left join courier cour on r.entity_id = cour.courierkey
where 1=1
and r.role_id in (
select role_id
from t_role_permission
where permission_id =301446)
group by r.role_id, r.role_name, r.active, r.created_ts,
decode( r.entity_type_id, 1000, m.name, 3000, cour.name, 4000, 'Ensenda' )
) A
where RN between 1 and 100 order by roleCreated desc
答案 2 :(得分:0)
作为regexp_like
路由的替代方法,您可以使用分析查询(尤其是analytic version of listagg()
)来实现此目的,并使用dense_rank()
生成限制性“行号”值:
select distinct role_id, role_name, active, companyName, permission_id,
permission_name, rn, total_rows, roleCreated
from (
select *
from (
select r.role_id,
r.role_name,
r.active,
decode(r.entity_type_id, 1000, m.name, 3000, cour.name,
4000, 'Ensenda') companyName,
p.permission_id as raw_permission_id,
listagg(p.permission_id, ' | ')
within group (order by p.permission_id)
over (partition by r.role_id) permission_id,
listagg(p.permission_name, ' | ')
within group (order by p.permission_id)
over (partition by r.role_id) permission_name,
dense_rank() over (order by r.created_ts desc) as rn,
count(distinct r.role_id) over () as total_rows,
r.created_ts roleCreated
from t_role r
left join t_role_permission rp ON r.role_id = rp.role_id
left join t_permission p ON rp.permission_id = p.permission_id
left join merchant m on r.entity_id = m.merchantkey
left join courier cour on r.entity_id = cour.courierkey
)
where raw_permission_id = 301446
)
where rn between 1 and 100
order by roleCreated desc;
如果你自己运行内部查询,你会看到每个role_id
的多个结果;每个都有listagg
个组件,但也会包含(暂时)个别permission_id
值,我将其别名为raw_permission_id
。
下一个查询可以过滤您感兴趣的确切权限对于单个权限,就像您在这里一样,每个角色最多只能提供一行,但如果您正在寻找其中一个一系列权限,然后你可能会得到重复(如果一个角色匹配多个)。因此,外部查询会排除raw_permission_id
并添加distinct
来抑制任何重复项。