需要 sql 查询以查找层次结构中最低级别的值
Need sql query to find the lowest level of values in a hierarchy
Table 组织(organizationId, parentId, name)
Table 设置(id、organizationId、settingName、settingValue)
这里是|a,1| : a是settingName,1是settingValue
Organization A |a,1| |b,2| |c,3| |d,4|
Organization B |b,5|
Organization C |a,8|
Organization D |c,2|
A->B->C->D(层级)
现在获取组织 D 的查询应该给我
(a,8)(b,5)(c,2)(d,4)
我的查询:
with recursive cte as (
select
*, 1 as level
from
Organization
where
organizationId = 3
union ALL
select
t.*, cte.level+1
from
cte
join Organization t on
t.OrganizationId = cte.parentId )
-- select
-- ss.OrganizationId,ss.parentId, ss.settingName,ss.settingValue
-- from
select
cte.OrganizationId,
cte.ParentId,
s.settingName ,
s.settingValue,
level
from
cte
inner join Settings s on
s.organizationId = cte.OrganizationId
-- as ss group by ss.settingName
这为我提供了所有组织的设置,但我需要来自父项的最近子项(如果有的话)的值(这应该一直持续到 ROOT 组织,自下而上的方法)
Settings Table Data
Organization table Data
跟踪感兴趣的组织 ID 和设置级别。按级别查找第一个值
with recursive cte as (
select s.*, 1 as level, s.organizationId as orgId
from Settings s
where s.organizationId = 4
union ALL
select s.*, cte.level+1, cte.orgId
from cte
join Organization t on t.organizationId = cte.organizationId
join settings s on s.organizationId = t.ParentId
)
select distinct orgid, settingname, first_value(settingvalue) over(partition by orgId, settingname order by level)
from cte
编辑
组织可以没有设置的情况
with recursive cte as (
select t.organizationId, s.settingname, s.settingvalue, 1 as level, t.organizationId orgId
from Organization t
left join Settings s on t.organizationId = s.organizationId
where t.organizationId = 5
union ALL
select t.ParentId, s.settingname, s.settingvalue, cte.level+1, cte.orgId
from cte
join Organization t on t.organizationId = cte.organizationId
left join settings s on s.organizationId = t.ParentId
)
select distinct orgid, settingname, first_value(settingvalue) over(partition by orgId, settingname order by level)
from cte
where settingName is not null
order by orgid, settingname;
创建架构
create table t42 (id number, parent_id number, flag varchar2(1), str
varchar2(20));
insert into t42 values (1, null, 'A', 'Parent');
insert into t42 values (2, 1, 'B', 'Child 1'); insert into t42
values (3, 1, 'C', 'Child 2'); insert into t42 values (4, 1, 'C',
'Child 3');
insert into t42 values (5, 2, 'D', 'Grandchild 1 1'); insert into
t42 values (6, 3, 'B', 'Grandchild 2 1'); insert into t42 values (7,
3, 'D', 'Grandchild 2 2');
现在执行下面的查询
select t.id, t.parent_id, t.flag, t.str
from (
select t.*, dense_rank() over (partition by flag order by lvl) as rn
from (
select t.*, level as lvl
from t42 t
start with parent_id is null
connect by prior id = parent_id
) t
) t
where rn = 1
and flag = 'A';
select t.id, t.parent_id, t.flag, t.str
from (
select t.*, dense_rank() over (partition by flag order by lvl) as rn
from (
select t.*, level as lvl
from t42 t
start with parent_id is null
connect by prior id = parent_id
) t
) t
where rn = 1
and flag = 'B';
select t.id, t.parent_id, t.flag, t.str
from (
select t.*, dense_rank() over (partition by flag order by lvl) as rn
from (
select t.*, level as lvl
from t42 t
start with parent_id is null
connect by prior id = parent_id
) t
) t
where rn = 1
and flag = 'C';
select t.id, t.parent_id, t.flag, t.str
from (
select t.*, dense_rank() over (partition by flag order by lvl) as rn
from (
select t.*, level as lvl
from t42 t
start with parent_id is null
connect by prior id = parent_id
) t
) t
where rn = 1
and flag = 'D';
Table 组织(organizationId, parentId, name) Table 设置(id、organizationId、settingName、settingValue)
这里是|a,1| : a是settingName,1是settingValue
Organization A |a,1| |b,2| |c,3| |d,4|
Organization B |b,5|
Organization C |a,8|
Organization D |c,2|
A->B->C->D(层级) 现在获取组织 D 的查询应该给我 (a,8)(b,5)(c,2)(d,4)
我的查询:
with recursive cte as (
select
*, 1 as level
from
Organization
where
organizationId = 3
union ALL
select
t.*, cte.level+1
from
cte
join Organization t on
t.OrganizationId = cte.parentId )
-- select
-- ss.OrganizationId,ss.parentId, ss.settingName,ss.settingValue
-- from
select
cte.OrganizationId,
cte.ParentId,
s.settingName ,
s.settingValue,
level
from
cte
inner join Settings s on
s.organizationId = cte.OrganizationId
-- as ss group by ss.settingName
这为我提供了所有组织的设置,但我需要来自父项的最近子项(如果有的话)的值(这应该一直持续到 ROOT 组织,自下而上的方法)
Settings Table Data
Organization table Data
跟踪感兴趣的组织 ID 和设置级别。按级别查找第一个值
with recursive cte as (
select s.*, 1 as level, s.organizationId as orgId
from Settings s
where s.organizationId = 4
union ALL
select s.*, cte.level+1, cte.orgId
from cte
join Organization t on t.organizationId = cte.organizationId
join settings s on s.organizationId = t.ParentId
)
select distinct orgid, settingname, first_value(settingvalue) over(partition by orgId, settingname order by level)
from cte
编辑 组织可以没有设置的情况
with recursive cte as (
select t.organizationId, s.settingname, s.settingvalue, 1 as level, t.organizationId orgId
from Organization t
left join Settings s on t.organizationId = s.organizationId
where t.organizationId = 5
union ALL
select t.ParentId, s.settingname, s.settingvalue, cte.level+1, cte.orgId
from cte
join Organization t on t.organizationId = cte.organizationId
left join settings s on s.organizationId = t.ParentId
)
select distinct orgid, settingname, first_value(settingvalue) over(partition by orgId, settingname order by level)
from cte
where settingName is not null
order by orgid, settingname;
创建架构
create table t42 (id number, parent_id number, flag varchar2(1), str
varchar2(20));
insert into t42 values (1, null, 'A', 'Parent');
insert into t42 values (2, 1, 'B', 'Child 1'); insert into t42
values (3, 1, 'C', 'Child 2'); insert into t42 values (4, 1, 'C',
'Child 3');
insert into t42 values (5, 2, 'D', 'Grandchild 1 1'); insert into
t42 values (6, 3, 'B', 'Grandchild 2 1'); insert into t42 values (7,
3, 'D', 'Grandchild 2 2');
现在执行下面的查询
select t.id, t.parent_id, t.flag, t.str
from (
select t.*, dense_rank() over (partition by flag order by lvl) as rn
from (
select t.*, level as lvl
from t42 t
start with parent_id is null
connect by prior id = parent_id
) t
) t
where rn = 1
and flag = 'A';
select t.id, t.parent_id, t.flag, t.str
from (
select t.*, dense_rank() over (partition by flag order by lvl) as rn
from (
select t.*, level as lvl
from t42 t
start with parent_id is null
connect by prior id = parent_id
) t
) t
where rn = 1
and flag = 'B';
select t.id, t.parent_id, t.flag, t.str
from (
select t.*, dense_rank() over (partition by flag order by lvl) as rn
from (
select t.*, level as lvl
from t42 t
start with parent_id is null
connect by prior id = parent_id
) t
) t
where rn = 1
and flag = 'C';
select t.id, t.parent_id, t.flag, t.str
from (
select t.*, dense_rank() over (partition by flag order by lvl) as rn
from (
select t.*, level as lvl
from t42 t
start with parent_id is null
connect by prior id = parent_id
) t
) t
where rn = 1
and flag = 'D';