我需要確保我們支持基于“父/子”表創建層次結構表。例子:
| F | 小號 |
|---|---|
| 一個 | b |
| b | C |
| b | d |
| b | 電子 |
| 電子 | F |
| 電子 | G |
| b | 米 |
| z | n |
| 米 | k |
預期結果:
| 大號 | L1 | L2 | L3 |
|---|---|---|---|
| 一個 | b | C | |
| 一個 | b | d | |
| 一個 | b | 電子 | |
| 電子 | F | ||
| 電子 | G | ||
| 一個 | b | 米 | k |
| z | n |
任何想法,建議?
謝謝
uj5u.com熱心網友回復:
前三個級別:
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 不是您使用的技術,那么請將以上內容視為偽代碼。
uj5u.com熱心網友回復:
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
| ID | 根 | l1 | l2 | l3 | l4 |
|---|---|---|---|---|---|
| 一個 | 一個 | 無效的 | 無效的 | 無效的 | 無效的 |
| z | z | 無效的 | 無效的 | 無效的 | 無效的 |
| b | 一個 | b | 無效的 | 無效的 | 無效的 |
| n | z | n | 無效的 | 無效的 | 無效的 |
| 米 | 一個 | b | 米 | 無效的 | 無效的 |
| 電子 | 一個 | b | 電子 | 無效的 | 無效的 |
| d | 一個 | b | d | 無效的 | 無效的 |
| C | 一個 | b | C | 無效的 | 無效的 |
| k | 一個 | b | 米 | k | 無效的 |
| G | 一個 | b | 電子 | G | 無效的 |
| F | 一個 | b | 電子 | F | 無效的 |
小提琴
uj5u.com熱心網友回復:
感謝您的回答。
我只能用 sql 語言查詢表,我不知道表中的最大級別數。
謝謝
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/536545.html
