Oracle Sql。带连接的递归选择
我有一个包含应用程序的表和一个包含消息的表。应用程序具有层次结构,例如每个应用程序都有一个父级。我有一张有留言的桌子。每条消息都有一个键和一个应用程序id。我希望能够通过它的键来选择消息。如果为当前应用程序找到它,则返回它,如果没有,则尝试使用父id查找它。 应用程序表:Oracle Sql。带连接的递归选择,sql,oracle,Sql,Oracle,我有一个包含应用程序的表和一个包含消息的表。应用程序具有层次结构,例如每个应用程序都有一个父级。我有一张有留言的桌子。每条消息都有一个键和一个应用程序id。我希望能够通过它的键来选择消息。如果为当前应用程序找到它,则返回它,如果没有,则尝试使用父id查找它。 应用程序表: id | name | parentId -------------------- 1 |parent| NULL 2 |child | 1 Msg表格: key | text
id | name | parentId
--------------------
1 |parent| NULL
2 |child | 1
Msg表格:
key | text | app
-------------------------------------------------
overriden.system.msg | some text | 1
parent.msg | parent txt | 1
overriden.system.msg | overriden text | 2
因此,如果我在key overriden.system.msg上的子应用程序(2)中,我希望获得覆盖文本。在key parent.msg上,我想获取parent txt。我知道这必须用cte来完成,但我对sql几乎没有什么过期性,cte现在对我来说是令人兴奋的。您能提供这种情况的工作查询吗?或者,您对如何在不使用递归的情况下实现此类功能有更好的了解?上述功能应该可以正常工作:
with app_tree (id, app, lvl) as
( select id , parentID , 0
from Apps
where id = 2
union all
select t.app, a.parentID, t.lvl + 1 from
Apps a
join app_tree t
on t.app = a.id ),
all_msg as (
select key, text,
row_number() over ( partition by key order by lvl) overrideLevel
from app_tree a
join msg m
on m.app = a.id )
select * from all_msg where
overrideLevel =1
它返回:
KEY TEXT
-------------------------------------
overriden.system.msg overriden text
parent.msg parent txt
首先,它使用带有parentid
的递归查询获取指定id的所有应用程序的列表。之后,它将获得所有应用程序的所有函数的列表,并根据级别为相同的键生成越来越多的数字。最后,它只取第一个可能的级别,并忽略同一个键的所有父级级别 Mb它将帮助您:
with app (id, name, parent_id) as
(select 1, 'parent', null from dual union all
select 2, 'child', 1 from dual)
,msg (key, text, app) as
(select 'overriden.system.msg', 'some text', 1 from dual union all
select 'parent.msg', 'parent txt', 1 from dual union all
select 'overriden.system.msg', 'overriden text', 2 from dual)
select key
,max(text) keep (dense_rank last order by nvl2(text,level,0)) msg
from
(select *
from app a
join msg m on (a.id = m.app)) v
start with v.parent_id is null
connect by prior v.id = v.parent_id and prior v.key = v.key
group by key