我有一个包含应用程序的表和包含消息的表。应用程序具有分层结构,例如每个应用程序都有父级。我有一张信息表。每条消息都有一个密钥和一个应用程序ID。我希望能够通过它的密钥选择消息。如果找到当前应用程序然后返回它,如果没有,则尝试使用父ID找到它。 应用表:
id | name | parentId
--------------------
1 |parent| NULL
2 |child | 1
消息表:
key | text | app
-------------------------------------------------
overriden.system.msg | some text | 1
parent.msg | parent txt | 1
overriden.system.msg | overriden text | 2
因此,如果我在关键 overriden.system.msg 的子app(2)中,我想要覆盖文本。在密钥 parent.msg 上,我想获得 parent txt 。我知道它必须用cte来完成,但是我对sql的解释很少,cte对我来说是令人兴奋的。你能否提供这种情况的工作查询?或者您可以更好地了解如何在没有递归的情况下实现此类功能?
答案 0 :(得分:1)
上述应该可以正常工作:
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的所有应用程序的列表。之后,它会获得所有应用程序的所有函数列表,并根据级别为相同的键生成不断增加的数字。最后,它只取第一个可能的级别并忽略同一个键的所有父级别。
答案 1 :(得分:1)
它会帮助你:
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