web-dev-qa-db-ja.com

OracleのCONNECT BY ... START WITHと同等のPostgreSQL構文は何ですか?

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でどのように行われますか?

18
dacracot

使う RECURSIVE CTE Postgresの場合:

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;

以前の回答の詳細とドキュメントへのリンク:

33

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);
8
Stradas

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;
0
sunrelax