Bonsoir Vincent,
D’accord, mais il y a un petit problème : du fait de la cardinalité 1,1, chaque catégorie contient plus ou moins directement sa catégorie parente 
Avec une cardinalité 0,1, on pourra éviter le cycle.
Looping produit alors le code SQL suivant :
CREATE TABLE Categorie
(
CategorieId CHAR(4),
CategorieNom VARCHAR(50),
CategorieId_parent CHAR(4),
CONSTRAINT Categorie_PK PRIMARY KEY(CategorieId),
CONSTRAINT Categorie_Categorie_parent_FK FOREIGN KEY(CategorieId_parent) REFERENCES Categorie(CategorieId)
);
Mais comme je ne tiens pas à la présence du bonhomme NULL, je procède à une scissiparité :
CREATE TABLE Categorie
(
CategorieId Char(4) NOT NULL
, CategorieNom Varchar(32) NOT NULL
, CONSTRAINT Categorie_PK PRIMARY KEY (CategorieId)
) ;
CREATE TABLE Contient
(
EnfantId Char(4) NOT NULL
, ParentId Char(4) NOT NULL
, CONSTRAINT Contient_PK PRIMARY KEY (EnfantId)
, CONSTRAINT Contient_FK1 FOREIGN KEY (EnfantId)
REFERENCES Categorie (CategorieId)
, CONSTRAINT Contient_FK2 FOREIGN KEY (ParentId)
REFERENCES Categorie (CategorieId)
) ;
Quelques inserts :
INSERT INTO Categorie VALUES ('e01', 'Categorie 01') ;
INSERT INTO Categorie VALUES ('e02', 'Categorie 02') ;
INSERT INTO Categorie VALUES ('e03', 'Categorie 03') ;
INSERT INTO Categorie VALUES ('e04', 'Categorie 04') ;
INSERT INTO Categorie VALUES ('e05', 'Categorie 05') ;
INSERT INTO Categorie VALUES ('e06', 'Categorie 06') ;
INSERT INTO Categorie VALUES ('e07', 'Categorie 07') ;
INSERT INTO Categorie VALUES ('e08', 'Categorie 08') ;
INSERT INTO Categorie VALUES ('e09', 'Categorie 09') ;
INSERT INTO Categorie VALUES ('e10', 'Categorie 10') ;
Recherche de la descendance des catégories à partir de l’ancêtre 'e01' :
WITH DESCENDANCE (ParentId, EnfantId) AS
(
(
SELECT ParentId, EnfantId
FROM Contient
WHERE ParentId = 'e01'
)
UNION ALL
(SELECT x.ParentId, x.EnfantId
FROM Contient AS x JOIN DESCENDANCE AS y
ON y.EnfantId = x.ParentId
)
)
Recherche de l’ascendance du jeunot 'e06' :
WITH ASCENDANCE (EnfantId, ParentId) AS
(
(
SELECT EnfantId, ParentId
FROM Contient
WHERE EnfantId = 'e06'
)
UNION ALL
(SELECT x.EnfantId, x.ParentId
FROM Contient AS x JOIN ASCENDANCE AS y
ON x.EnfantId = y.ParentId
)
)
SELECT DISTINCT y.CategorieNom AS Enfant, z.CategorieNom AS Parent
FROM ASCENDANCE x
JOIN Categorie y ON x.EnfantId = y.CategorieId
JOIN Categorie z ON x.ParentId = z.CategorieId
;
En gros, j‘ai repris ce que j’avais proposé ici, en 2010...
Je constate que nous avions pas mal échangé en 2016, à propos de télescopes 
Qu'en sera-t-il en 2030 ?
Partager