在 Oracle 中,如果我将表定义为...
CREATE TABLE taxonomy
(
key NUMBER(11) NOT NULL CONSTRAINT taxPkey PRIMARY KEY,
value VARCHAR2(255),
taxHier NUMBER(11)
);
ALTER TABLE
taxonomy
ADD CONSTRAINT
taxTaxFkey
FOREIGN KEY
(taxHier)
REFERENCES
tax(key);
有了这些价值......
key value taxHier
0 zero null
1 one 0
2 two 0
3 three 0
4 four 1
5 five 2
6 six 2
此查询语法...
SELECT
value
FROM
taxonomy
CONNECT BY
PRIOR key = taxHier
START WITH
key = 0;
会屈服......
zero
one
four
two
five
six
three
如何在 PostgreSQL 中完成?
答案 0 :(得分:25)
在Postgres中使用RECURSIVE CTE
:
WITH RECURSIVE cte AS (
SELECT key, value, 1 AS level
FROM taxonomy
WHERE key = 0
UNION ALL
SELECT t.key, t.value, c.level + 1
FROM cte c
JOIN taxonomy t ON t.taxHier = c.key
)
SELECT value
FROM cte
ORDER BY level;
我之前回答中文档的详细信息和链接:
答案 1 :(得分:6)
Postgres确实具有与connect by相当的功能。您需要启用该模块。它默认关闭。
它被称为 tablefunc 。它支持一些很酷的交叉表功能以及熟悉的" 连接"和" 开始"。我发现它比递归CTE更有说服力和逻辑性。如果你的DBA无法启用此功能,那么你应该选择Erwin的方式。
它足够强大,能够完成"材料清单"类型查询也是如此。
可以通过运行以下命令打开Tablefunc:
CREATE EXTENSION tablefunc;
以下是从官方文档中刚刚解除的连接字段列表。
Parameter: Description
relname: Name of the source relation (table)
keyid_fld: Name of the key field
parent_keyid_fld: Name of the parent-key field
orderby_fld: Name of the field to order siblings by (optional)
start_with: Key value of the row to start at
max_depth: Maximum depth to descend to, or zero for unlimited depth
branch_delim: String to separate keys with in branch output (optional)
你真的应该看看文档页面。它写得很好,它会为您提供您习惯的选项。 (在文档页面向下滚动,靠近底部。)
Postgreql "Connect by" extension 下面是将该结构放在一起的描述。有很大的潜力,所以我不会做正义,但这里有一个秘密给你一个想法。
connectby(text relname, text keyid_fld, text parent_keyid_fld
[, text orderby_fld ], text start_with, int max_depth
[, text branch_delim ])
真正的查询将如下所示。 Connectby_tree是表的名称。以" AS"开头的行是你如何命名列。它确实看起来有点颠倒。
SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
AS t(keyid text, parent_keyid text, level int, branch text, pos int);
答案 2 :(得分:0)
如Stradas所示,我报告了该查询:
SELECT value
FROM connectby('taxonomy', 'key', 'taxHier', '0', 0, '~')
AS t(keyid numeric, parent_keyid numeric, level int, branch text)
inner join taxonomy t on t.key = keyid;