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
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
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);
où 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 UNION
ed 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.
@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:
J'espère que cela aide quelqu'un!
maintenant, je me demande comment faire cela sur MySQL... ^^
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.