[英]SQL Oracle : how to find records maching a particular id in the column
我的查詢是:
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
將不會產生所需的結果。
根據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;
對於大型數據集,其中您要查找的permission_id的值不常見,查詢整個數據集然后對聚合結果進行過濾將是非常低效的,並且看起來似乎是邏輯上不正確的結果。
您要查找的內容不是權限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
作為regexp_like
路由的替代方法,您可以使用分析查詢(特別是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
以抑制任何重復。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.