postgresql层次结构表基于两列

kfgdxczn  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(3)|浏览(239)

我需要确保我们支持基于“父/子”表创建层次结构表。例如:
| F级|标准|
| - -|- -|
| 一种|B|
| B| C语言|
| B|日|
| B|电子|
| 电子|关闭|
| 电子|克|
| B|米|
| Z轴|n个|
| 米|k型|
预期结果:
| 左|一级|二级|三级|
| - -|- -|- -|- -|
| 一种|B| C语言||
| 一种|B|日||
| 一种|B|电子||
| 电子|关闭|||
| 电子|克|||
| 一种|B|米|k型|
| Z轴|n个|||
有什么想法,建议吗?
谢谢你

np8igboo

np8igboo1#

前三层:

SELECT L0.F AS L, L1.F AS L1, L2.F AS L2, L3.S AS L3
FROM t L0
LEFT JOIN t L1
ON L0.S = L1.F
LEFT JOIN t L2
ON L1.S = L2.F
LEFT JOIN t L3
ON L2.S = L3.S
LEFT JOIN t nonexistent
ON L0.F = nonexistent.S
WHERE nonexistent.S IS NULL

说明:

  • 尺寸1为L0
  • 尺寸2为L1
  • 尺寸3为L2
  • 我们通过仅保留没有父级的L0记录来确保L0没有父级

也许你需要改变一些逻辑,请让我知道,如果我误解了确切的意图。
一般来说,如果你需要n个层次,那么你就需要生成代码。在PHP中,你可以这样做:

$SELECT = "SELECT L0.F AS L";
$FROM = "t L0";
for ($index = 1; $index < $n; $index++) {
    $SELECT .= ", L{$index}.F AS L{$index}";
    $FROM .= " LEFT JOIN L" . $index . " ON L" . ($index - 1) . ".S = L" . $index . "F";
}
$FROM .= " LEFT JOIN t nonexistent ON L0.F = nonexistent.S ";
WHERE = "WHERE nonexistent.S IS NULL";
$query = "{$SELECT} ${FROM} {$WHERE}";

当然,您可以使用您喜欢的语言来生成这样的n维选择,如果PHP不是您使用的技术,那么请将上面的代码视为伪代码。

2eafrhcq

2eafrhcq2#

with 
recursive cte(id, path) as
(
select f, f::text from   t where  f not in(select s from t where s is not null)
union all
select t.s, cte.path || '/' || t.s from cte join t on cte.id = t.f 
)

select  id      
       ,path[1] as root
       ,path[2] as l1
       ,path[3] as l2
       ,path[4] as l3
       ,path[5] as l4
from 
(
select  id 
       ,regexp_split_to_array(path, '/') as path
from    cte
) cte

| 标识符|根|第一层|二级|三级|第四层|
| - -|- -|- -|- -|- -|- -|
| 一种|一种|零值|零值|零值|零值|
| Z轴|Z轴|零值|零值|零值|零值|
| B|一种|B|零值|零值|零值|
| n个|Z轴|n个|零值|零值|零值|
| 米|一种|B|米|零值|零值|
| 电子|一种|B|电子|零值|零值|
| 日|一种|B|日|零值|零值|
| C语言|一种|B| C语言|零值|零值|
| k型|一种|B|米|k型|零值|
| 克|一种|B|电子|克|零值|
| 关闭|一种|B|电子|关闭|零值|
Fiddle

7cwmlq89

7cwmlq893#

谢谢你的回答。
我只能用sql语言查询表,我不知道我在表中的最大级别数。
谢谢

相关问题