我有包含客户区域的表“ Areas”:
ID, AREA_NAME, PARENT_ID
区域使用指向父级的AREA_ID的PARENT_ID分为四个层次。顶层区域的PARENT_ID为NULL。
“客户”表具有引用区域层次结构最低级别的AREA_ID:
ID, CUSTOMER_NAME, AREA_ID
我想得到这样的结果表:
CUSTOMER_NAME,AREA_LVL_1,AREA_LVL_2,AREA_LVL_3,AREA_LVL_4
这里的问题是客户区域(AREA_ID)始终不指向最低的第四级区域。有时它指向第四级AREA_ID,有时指向第三级,依此类推。
取决于区域级别,结果表应如下所示:
CUSTOMER_NAME | AREA_LVL_1 | AREA_LVL_2 | AREA_LVL_3 | AREA_LVL_4
==============+============+============+============+===========
John | A | A1 | A13 | A136
Maria | B | B2 | <null> | <null>
Steve | A | A2 | A24 | <null>
我不知道如何在单个SQL查询中使用可变数量的级别进行此递归。我只需要单个SQL查询(而不是带有游标通过递归循环的过程)。
您需要一个递归的CTE
,它返回将要加入customers
的每个区域的所有级别:
with
cte as (
select id, area_name, parent_id, id start, 4 level from areas
union all
select a.id, a.area_name, a.parent_id, c.start, c.level - 1
from areas a inner join cte c
on c.parent_id = a.id
where c.parent_id is not null
),
levels as (
select id, area_name, parent_id, start,
level + 1 - min(level) over (partition by start) level
from cte
)
select c.customer_name,
max(case when l.level = 1 then l.area_name end) area_lvl_1,
max(case when l.level = 2 then l.area_name end) area_lvl_2,
max(case when l.level = 3 then l.area_name end) area_lvl_3,
max(case when l.level = 4 then l.area_name end) area_lvl_4
from customers c left join levels l
on l.start = c.area_id
group by c.id, c.customer_name
请参见demo。结果:
> customer_name | area_lvl_1 | area_lvl_2 | area_lvl_3 | area_lvl_4
> :------------ | :--------- | :--------- | :--------- | :---------
> John | A | A1 | A13 | A136
> Maria | B | B2 | null | null
> Steve | A | A2 | A24 | null