2009-02-17 5 views
1

J'ai donc cette table, avec 3 colonnes: ID (clé unique), PositionID et SupervisorID. PositionID et SupervisorID sont les deux clés étrangères d'une table Positions.requête SQL difficile

Ce que je n'ai pas été en mesure de comprendre est une manière décemment agréable d'obtenir hérités subordonnés. Ainsi, par exemple:


IDPositionIDSupervisorID

1  2   1 

2  2   3 

3  3   4 

4  1   5 
... 

comment pourrais-je choisir 2,3 et 4 en fonction de leur position subordonnée à 1. La solution actuelle est tout à fait une manière désordonnée de le faire, et il semble assez commun d'un problème que peut-être il y a une méthode acceptée.

Merci.

Répondre

1

Vous pouvez le faire à une certaine profondeur avec le SQL standard (et probablement toute profondeur avec diverses améliorations SQL), mais les déclarations SQL seront des abominations hideuses des profondeurs de l'enfer de Satan. SQL est une algèbre relationnelle, pas quelque chose à être plié à un modèle procédural. Sérieusement, utilisez du code pour cela (même s'il s'agit d'une procédure stockée ou PL/SQL), cela rendra votre SQL plus joli, vos administrateurs de bases de données et futurs responsables plus heureux et votre vie plus longue et plus prospère.

+0

Oui, intuitivement, il ne semblait pas qu'une profondeur illimitée puisse être faite avec SQL direct. C'est dans une procédure stockée. Certaines autres procédures stockées traitant de cette fonctionnalité créent des tables temporaires pendant la procédure (shriek!). –

+0

Vous n'avez pas besoin de tables temporaires. Si vous disposez d'une implémentation SP décente, vous pouvez la coder dans n'importe quelle langue (nous utilisons REXX pour DB2/z) et stocker vos informations intermédiaires en mémoire. – paxdiablo

2

Si vous avez un Microsoft SQL Server 2008, vous devriez regarder le HierarchyId type de données. Je pense que c'est exactement ce que vous cherchez. Vous pouvez le faire sans ce type mais alors vous devrez écouter les autres gars. ;)

0

J'ai écrit des requêtes pour faire exactement ceci et exploser des nomenclatures. J'ai utilisé une requête dans une boucle while qui sélectionne une table temporaire et des expressions de table communes récursives. Pour autant que je sache, ce sont les seuls moyens d'utiliser une fonction récursive/sproc - qui est un non dans une base de données de production (à mon avis) pour une variété de raisons (d'abord puisque le serveur SQL est limité à 16 niveaux par défaut). Je peux poster du code si demandé.

2

Vous pouvez essayer:

WITH HierarchyCTE (ID, PositionID, SupervisorID) 
    AS 
    (
     SELECT ID, PositionID, SupervisorID 
     FROM SomeTable 
     WHERE ID = 1 
     UNION ALL 
     SELECT b.ID, b.PositionID, b.SupervisorID 
     FROM SomeTable AS b 
     INNER JOIN HierarchyCTE AS c ON b.ID = c.PositionID 
    ) 
    SELECT ID, PositionID, SupervisorID FROM HierarchyCTE 

ou quelque chose proche de qui devrait fonctionner.