Dans Oracle, si j'ai une table définie comme…
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);
Avec ces valeurs…
key value taxHier
0 zero null
1 one 0
2 two 0
3 three 0
4 four 1
5 five 2
6 six 2
Cette syntaxe de requête…
SELECT
value
FROM
taxonomy
CONNECT BY
PRIOR key = taxHier
START WITH
key = 0;
Donnera…
zero
one
four
two
five
six
three
Comment cela se fait-il dans PostgreSQL?
Utiliser un RECURSIVE CTE
dans 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;
Détails et liens vers la documentation dans ma réponse précédente:
Postgres a un équivalent de la connexion par. Vous devrez activer le module. Son désactivé par défaut.
Il est appelé tablefunc . Il prend en charge certaines fonctionnalités de tableau croisé ainsi que les familiers " se connectent par " et " Commencer par ". J'ai trouvé qu'il fonctionne beaucoup plus éloquemment et logiquement que le CTE récursif. Si vous ne pouvez pas activer cela avec votre DBA, vous devriez opter pour la façon dont Erwin le fait.
Il est suffisamment robuste pour effectuer également la requête de type "nomenclature".
Tablefunc peut être activé en exécutant cette commande:
CREATE EXTENSION tablefunc;
Voici la liste des champs de connexion fraîchement extraits de la documentation officielle.
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)
Vous devriez vraiment jeter un œil à la page des documents. Il est bien écrit et vous donnera les options auxquelles vous êtes habitué. (Sur la page doc, faites défiler vers le bas, c'est près du bas.)
Postgreql "Connect by" extension Ci-dessous est la description de ce que devrait être la mise en place de cette structure. Il y a une tonne de potentiel, donc je ne lui rendrai pas justice, mais en voici un extrait pour vous donner une idée.
connectby(text relname, text keyid_fld, text parent_keyid_fld
[, text orderby_fld ], text start_with, int max_depth
[, text branch_delim ])
Une vraie requête ressemblera à ceci. Connectby_tree est le nom de la table. La ligne commençant par "AS" est la façon dont vous nommez les colonnes. Cela semble un peu à l'envers.
SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
AS t(keyid text, parent_keyid text, level int, branch text, pos int);
Comme indiqué par Stradas, je signale la requête:
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;