|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||||||||||
|
Invité de passage
![]() Développeur en systèmes embarqués Inscription : novembre 2011 Messages : 3 ![]() |
Bonjour,
J'ai une table contenant des données (des machins dans mon exemple) et une table de liens utilisée pour représenter ces données en arbre. Mon problème est de pouvoir sélectionner tous les descendants d'un même élément. Exemple : Création de la table machin : Code :
Code :
Code :
Code :
Code :
Code :
Je ne sais pas du tout si il est possible de faire ça en une requête SQL. Je ne suis pas développeur SQL et il y a surement des techniques standard pour ce problème qui m'échappent (j'ai bien essayé des trucs avec WITH RECURSIVE mais j'ai pas du comprendre comment l'utiliser correctement). Note: J'utilise postgresql (8.4), je ne suis pas contre une fonction plpgsql recursive. d'avance merci |
||||||||||||
|
|
00
|
|
|
#2 |
|
Membre Expert
![]() Inscription : mars 2005 Messages : 1 565 ![]() |
Vous êtes sur la bonne voie. Un lien vers le cours d'SQLPro sur les CTE (mécanisme de SQL qui permet la récursivité notamment) : http://sqlpro.developpez.com/cours/s...ecursives/#LIV
Il y a un exemple de requête qui parcours un arbre modélisé par auto référence comme dans votre modèle. |
|
|
00
|
|
|
#3 | ||||
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
En postgresql ça devrait donner ça (ça te donne un autre exemple):
Code :
Code :
|
||||
|
|
00
|
|
|
#4 |
![]() ![]() ![]() Frédéric BROUARDExpert SGBDR & SQL Inscription : mai 2002 Messages : 10 959 ![]() |
Sauf que votre modèle est incorrect. Vous avez créé une table de liens, alors que vous voulez représenter un arbre.
Il aurait suffit de mettre une auto référence. Dans votre modèle, vous n'avez pas modélisé un arbre mais un graphe au sens mathématique du terme (réseau). Donc vos requêtes sont incorrecte compte tenu du modèle et en sus vous pouvez avoir des cycles ! A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/ Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp. Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * * |
|
00
|
|
|
#5 | ||||||
|
Invité de passage
![]() Développeur en systèmes embarqués Inscription : novembre 2011 Messages : 3 ![]() |
Merci vmoline, en fait j'avais survolé WITH RECURSIVE (et veinement tenté l'écriture de fonction pglsql) alors que WITH RECURSIVE semble bien être la solution.
Donc j'ai fait comme ceci (pour recupérer tout les descendant de l'id 1) : Code :
Code :
merci skuatamad, mais la première requête (dans postgres 8.4) me dit : Code :
Merci pour vos réponses si rapides
|
||||||
|
|
00
|
|
|
#6 |
|
Membre Expert
![]() Pacman PacmanBusiness analyst Inscription : juin 2004 Messages : 1 417 ![]() |
Salut !
En fait, il considère que NULL est de type text, or il faut que ça matche avec l'id. Tente peut-être de remplacer par CAST(NULL AS INTEGER) ou un truc du genre...
__________________
(c'est ma photo) Paku, Paku ! Pour les jeunes incultes : non, je ne suis pas un pokémon... Le pacblog : http://pacmann.over-blog.com/ |
|
00
|
|
|
#7 |
|
Membre Expert
![]() Inscription : mars 2005 Messages : 1 565 ![]() |
Pour revenir sur mon conseil, il n'est pas tout à fait bon puisque votre modèle (que je n'ai pas lu en m'empressant de répondre) n'utilise pas l'auto référence comme l'a justement souligné SQLPro.
|
|
|
00
|
|
|
#8 |
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
Et comme ça ?
Code :
SELECT cast(NULL AS integer) AS id_parent, |
|
|
00
|
|
|
#9 | |
|
Invité de passage
![]() Développeur en systèmes embarqués Inscription : novembre 2011 Messages : 3 ![]() |
Citation:
Mais bon maintenant que la base est faite il faut l'utiliser comme elle est... ![]() En fait l'application qui insère des données dans la table le fait de sorte que les données forment bien un arbre (donc pas de cycles). C'est pas idéal et l'idée de départ s'est transformée en mauvaise conception. Il est prévu (et je me battrai pour) de changer ce modèle lors de la prochaine version majeure du soft. pacmann+skuatamad : avec CAST(NULL AS INTEGER) ça passe effectivement, merci |
|
|
|
00
|
|
|
#10 | ||||||||
|
Expert Confirmé Sénior
![]() ![]() ![]() Spécialiste en bases de données Inscription : septembre 2006 Messages : 2 884 ![]() |
Bonsoir,
La discussion est marquée résolue, mais je souhaite quand même intervenir, car ce qui a été dit hier est parfois contestable et les conclusions un peu hâtives. 1) L’utilisation de l’auto-référence n’interdit pas les cycles. Exemple : Code SQL :
Code :
2) L’utilisation de l’auto-référence n’exclut pas non plus la possibilité de représenter des graphes. Exemple : Code SQL :
Code :
3) Aux cycles près toujours possibles, la table de liens définie par ctxctx n’autorise que des structures arborescentes. Ceci est la conséquence de la présence de la clé candidate {id_machin_child} : CONSTRAINT link_machin_machin_id_machin_child_key UNIQUE (id_machin_child)La seule modification à apporter consiste donc à évacuer la clé primaire actuelle {id_machin_parent, id_machin_child} de la table link_machin_machin en la remplaçant par le singleton {id_machin_child}. 4) L’utilisation de l’auto-référence est en fait intéressante pour les opérations de suppression en cascade (si le SGBD le permet), sinon il faut mettre en œuvre de la programmation pour pallier (selon la représentation de ctxctx, l’utilisation de la clause ON DELETE CASCADE permet seulement de supprimer les liens entre un enfant et son parent).
__________________
_ Faites simple, mais pas plus simple ! (A. Einstein) E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire ») => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale ») __________________ Bases de données relationnelles et normalisation : de la première à la sixième forme normale (Bonne lecture !) |
||||||||
|
|
20
|
|
|
#11 | ||||||||||
|
Expert Confirmé Sénior
![]() ![]() ![]() Spécialiste en bases de données Inscription : septembre 2006 Messages : 2 884 ![]() |
Bonsoir,
En complément : un exemple d’instructions (SQL Server) pour supprimer un noeud et ses descendants quand il n'y a pas auto-référence, c'est-à-dire dans le style de ctxctx. Les cracks de SQL ne manquement pas d’améliorer ce modeste essai. Création des tables PIECE et NOMENCLATURE à la façon de ctxctx (noter la clause ON DELETE CASCADE sans laquelle la suppression ensembliste échoue) : Code SQL :
Création d’une fonction permettant de récupérer un nœud et ses descendants : Code SQL :
Suppression en cascade des liens qu’entretient la pièce 3 avec ses descendantes : Code SQL :
Jeu d’essai (table PIECE) : Code SQL :
Jeu d’essai (table NOMENCLATURE) : Code SQL :
Nomenclature avant suppression des liens avec la pièce 3 : ![]() Après suppression :
__________________
_ Faites simple, mais pas plus simple ! (A. Einstein) E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire ») => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale ») __________________ Bases de données relationnelles et normalisation : de la première à la sixième forme normale (Bonne lecture !) |
||||||||||
|
|
30
|
|
|
#12 |
|
Membre Expert
![]() Pacman PacmanBusiness analyst Inscription : juin 2004 Messages : 1 417 ![]() |
Salut,
Juste une question : les contraintes ne sont-elles pas validées "en bloc" pour une même requête SQL ?
__________________
(c'est ma photo) Paku, Paku ! Pour les jeunes incultes : non, je ne suis pas un pokémon... Le pacblog : http://pacmann.over-blog.com/ |
|
00
|
|
|
#13 | |
|
Expert Confirmé Sénior
![]() ![]() ![]() Spécialiste en bases de données Inscription : septembre 2006 Messages : 2 884 ![]() |
Bonjour vigilant pacmann,
Citation:
On est donc désormais dans le paradigme du « tout ou rien ». Si un « NO ACTION » joue son rôle, en cas d’infraction de notre part le résultat d’une requête SQL de suppression (ou de modification) est annulée en bloc, ce qui est tout de même plus rassurant qu’avec IMS/DL1. Mais l’adhésion des constructeurs de SGBD au paradigme peut les conduire à certaines options mal venues dans la mise en œuvre, je vous renvoie à ce sujet au message dans lequel je rappelle que les pères de DB2 et SQL Server ont fait des choix différents et qui sont infondés si l’on suit Chris Date qui place le niveau « en bloc » à un niveau supérieur, cf. Database Explorations, Essays on The Third Manifesto and Related Topics, page 224.
__________________
_ Faites simple, mais pas plus simple ! (A. Einstein) E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire ») => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale ») __________________ Bases de données relationnelles et normalisation : de la première à la sixième forme normale (Bonne lecture !) |
|
|
|
00
|
|
|
#14 | |||||||
|
Expert Confirmé Sénior
![]() ![]() ![]() Spécialiste en bases de données Inscription : septembre 2006 Messages : 2 884 ![]() |
Bonsoir,
Citation:
Au lieu de : Suppression de la pièce 3 et de ses descendants : Code :
Suppression en cascade des liens qu’entretient la pièce 3 avec ses descendantes : Code :
Si en plus on veut aussi supprimer les pièces 3, 5, 6, 7, 8, 15, il est préférable de supprimer d’abord les liens directement dans la table NOMENCLATURE comme on vient de le faire et seulement après de supprimer les pièces : Code SQL :
__________________
_ Faites simple, mais pas plus simple ! (A. Einstein) E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire ») => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale ») __________________ Bases de données relationnelles et normalisation : de la première à la sixième forme normale (Bonne lecture !) |
|||||||
|
|
00
|
|
|
#15 | |
|
Membre Expert
![]() Pacman PacmanBusiness analyst Inscription : juin 2004 Messages : 1 417 ![]() |
Salut,
Mais ma remarque concernait effectivement juste : Citation:
Je pensais qu'il s'agissait d'une solution à une table avec auto-référence... du coup je me disais qu'il serait étrange que la validation de la requête dépende en quelque sorte du plan d'exécution (si on supprime les fils d'abord donc en triant par niveau, pas de problème). J'aime bien votre version revue (sûrement parce que je suis pas fan de cascades C'est peut-être juste une question de goût, mais une vue n'aurait-elle pas fait autant l'affaire qu'une fonction retournant une table (sans changer le reste de la mécanique) ?
__________________
(c'est ma photo) Paku, Paku ! Pour les jeunes incultes : non, je ne suis pas un pokémon... Le pacblog : http://pacmann.over-blog.com/ |
|
|
00
|
|
|
#16 | |||
|
Expert Confirmé Sénior
![]() ![]() ![]() Spécialiste en bases de données Inscription : septembre 2006 Messages : 2 884 ![]() |
Ave pacmann,
Citation:
Code SQL :
__________________
_ Faites simple, mais pas plus simple ! (A. Einstein) E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire ») => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale ») __________________ Bases de données relationnelles et normalisation : de la première à la sixième forme normale (Bonne lecture !) |
|||
|
|
00
|
|
|
#17 |
|
Membre Expert
![]() Pacman PacmanBusiness analyst Inscription : juin 2004 Messages : 1 417 ![]() |
Effectivement, je suis à côté de la plaque
On pourrait bien créer la vue sur sans pieceid et en ajoutant une colonne "root", puis filtrer sur root. Par contre, je pense que l'optimiseur n'arrivera pas à "push" le prédicat et que ça fait construire l'arbre en entier à chaque fois... J'essaierai de plus répondre sans réfléchir, c'est nul
__________________
(c'est ma photo) Paku, Paku ! Pour les jeunes incultes : non, je ne suis pas un pokémon... Le pacblog : http://pacmann.over-blog.com/ |
|
00
|
|
|
#18 | |
![]() ![]() ![]() Frédéric BROUARDExpert SGBDR & SQL Inscription : mai 2002 Messages : 10 959 ![]() |
Citation:
En effet, la mise à jour globale et par requête d'une colonne UNIQUE (PK par exemple), n'est toujours pas supportée ni par l'un ni par l'autre car les contraintes sont vérifiées lignes par ligne ! Pour PG il existe une solution de contournement (je sais pas si elle est encore en béta ou déjà en prod) pour différer la contrainte au niveau de la finalisation de la transaction.... A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/ Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp. Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * * |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com