45 votes

Simulation de CONNECT BY PRIOR of ORACLE dans SQL SERVER

Je souhaite bénéficier des fonctionnalités de CONNECT BY PRIOR d’ORACLE dans SQL SERVER 2000/2005/2008?

Aidez-moi, s'il vous plaît

72voto

Alex Martelli Points 330805

La norme SQL façon de mettre en œuvre des requêtes récursives, comme mises en œuvre, notamment par IBM DB2 et SQL Server, est l' WITH de la clause. Voir cet article pour un exemple de traduction d'un CONNECT BY en WITH (techniquement une expression de table commune récursive) -- l'exemple est pour DB2 mais je crois qu'il va travailler sur SQL Server.

Edit: apparemment l'original querant nécessite un exemple concret, voici une de la IBM site dont l'URL, j'ai déjà donné. Étant donné un tableau:

CREATE TABLE emp(empid  INTEGER NOT NULL PRIMARY KEY,
                 name   VARCHAR(10),
                 salary DECIMAL(9, 2),
                 mgrid  INTEGER);

mgrid références d'un employé du gestionnaire de l' empid, la tâche est, d'obtenir les noms de tout le monde qui rapporte directement ou indirectement à l' Joan. Dans Oracle, c'est un simple CONNECT:

SELECT name 
  FROM emp
  START WITH name = 'Joan'
  CONNECT BY PRIOR empid = mgrid

Dans SQL Server, IBM DB2 ou PostgreSQL 8.4 (ainsi que dans le standard SQL, pour ce que ça vaut le coup;-), la perfection de solution équivalente est plutôt une requête récursive (plus d'une syntaxe complexe, mais, en fait, encore plus de puissance et de souplesse):

WITH n(empid, name) AS 
   (SELECT empid, name 
    FROM emp
    WHERE name = 'Joan'
        UNION ALL
    SELECT nplus1.empid, nplus1.name 
    FROM emp as nplus1, n
    WHERE n.empid = nplus1.mgrid)
SELECT name FROM n

Oracle START WITH clause devient la première imbriquée SELECT, le cas de base de la récursivité, pour être UNIONed avec la partie récursive qui n'est qu'un SELECT.

SQL Server spécifiques de la saveur de l' WITH est bien sûr documenté sur MSDN, qui donne également des lignes directrices et des limites pour l'utilisation de ce mot-clé, ainsi que plusieurs exemples.

12voto

vinigarcia87 Points 757

@Alex Martelli's réponse est génial! Mais il ne travailler que pour un seul élément à la fois (WHERE name = 'Joan') Si vous sortez de la WHERE clause, la requête renvoie toutes les racines lignes ensemble...

J'ai changé un peu de ma situation, de sorte qu'il peut afficher la totalité de l'arbre pour une table.

la définition de la table:

CREATE TABLE [dbo].[mar_categories] ( 
    [category]  int IDENTITY(1,1) NOT NULL,
    [name]      varchar(50) NOT NULL,
    [level]     int NOT NULL,
    [action]    int NOT NULL,
    [parent]    int NULL,
    CONSTRAINT [XPK_mar_categories] PRIMARY KEY([category])
)

(level est littéralement le niveau d'une catégorie 0: root, 1: premier niveau après racine, ...)

et de la requête:

WITH n(category, name, level, parent, concatenador) AS 
(
    SELECT category, name, level, parent, '('+CONVERT(VARCHAR (MAX), category)+' - '+CONVERT(VARCHAR (MAX), level)+')' as concatenador
    FROM mar_categories
    WHERE parent is null
        UNION ALL
    SELECT m.category, m.name, m.level, m.parent, n.concatenador+' * ('+CONVERT (VARCHAR (MAX), case when ISNULL(m.parent, 0) = 0 then 0 else m.category END)+' - '+CONVERT(VARCHAR (MAX), m.level)+')' as concatenador
    FROM mar_categories as m, n
    WHERE n.category = m.parent
)
SELECT distinct * FROM n ORDER BY concatenador asc

(Vous n'avez pas besoin de concaténer l' level champ, je l'ai fait juste pour le rendre plus lisible)

la réponse à cette requête doit être quelque chose comme:

sql return

J'espère que cela aide quelqu'un!

maintenant, je me demande comment faire cela sur MySQL... ^^

1voto

Joel Coehoorn Points 190579

Je n'ai pas utilisé connect by avant, mais une recherche rapide montre qu'il est utilisé pour les arborescences. Dans SQL Server, vous utilisez des expressions de table courantes pour obtenir des fonctionnalités similaires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X