![](/img/trans.png)
[英]What is equivalent PostgreSQL syntax to Oracle's grouping_id?
[英]What is the equivalent PostgreSQL syntax to Oracle's CONNECT BY ... START WITH?
在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中完成的?
在 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;
我之前的回答中的详细信息和文档链接:
Postgres 确实有一个相当于 connect by 的东西。 您将需要启用该模块。 它默认关闭。
它被称为tablefunc 。 它支持一些很酷的交叉表功能以及熟悉的“ connect by ”和“ Start With ”。 我发现它比递归 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" 扩展下面是对将该结构组合在一起应该是什么样子的描述。 有很多潜力,所以我不会公正地对待它,但这里有一个片段给你一个想法。
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);
正如 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;
例如,我们在PostgreSQL中有一个表,它的名称是 product_types。 我们的表列是 (id, parent_id, name, sort_order)。 我们的第一个选择应该给(父母)一条根线。 id = 76 将是我们的 sql 的前 1 父记录。
with recursive product_types as (
select
pt0.id,
pt0.parant_id,
pt0.name,
pt0.sort_order,
0 AS level
from product_types pt0
where pt0.id = 76
UNION ALL
select
pt1.id,
pt1.parant_id,
pt1.name,
pt1.sort_order, (product_types.level + 1) as level
from product_types pt1
inner join product_types on (pt1.parant_id = product_types.id )
)
select
*
from product_types
order by level, sort_order
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.