Je voudrais obtenir la fonctionnalité de CONNECTER PAR PRIOR d'ORACLE dans SQL SERVER 2000/2005/2008?Simulation de CONNECTER PAR AVANT de ORACLE dans SQL SERVER
S'il vous plaît aidez-moi
Je voudrais obtenir la fonctionnalité de CONNECTER PAR PRIOR d'ORACLE dans SQL SERVER 2000/2005/2008?Simulation de CONNECTER PAR AVANT de ORACLE dans SQL SERVER
S'il vous plaît aidez-moi
La méthode standard SQL pour implémenter des requêtes récursives, mis en œuvre par exemple par IBM DB2 et SQL Server, est la clause WITH
. Voir this article pour un exemple de traduction d'un CONNECT BY
en un WITH
(techniquement un récursif CTE) - l'exemple est pour DB2 mais je crois qu'il fonctionnera aussi sur SQL Server.
Editer: apparemment le demandeur d'origine nécessite un exemple spécifique, en voici un du site IBM dont j'ai déjà donné l'URL. Compte tenu d'une table:
CREATE TABLE emp(empid INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(10),
salary DECIMAL(9, 2),
mgrid INTEGER);
où mgrid
références empid
est le gestionnaire d'un employé, la tâche est, obtenir les noms de tous ceux qui se rapporte directement ou indirectement à Joan
. Dans Oracle, qui 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 la norme SQL, pour ce que ça vaut ;-), la solution parfaitement équivalente est plutôt une récursif requête (syntaxe plus complexe, mais, en fait, encore plus de puissance et de flexibilité):
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
clause START WITH
Oracle devient le premier imbriqué SELECT
, le cas de base de la récursion, pour être UNION
ed avec la partie récursive qui est juste un autre SELECT
.
La syntaxe spécifique de SQL Server de WITH
est bien sûr documentée sur MSDN, qui fournit également des directives et des limitations pour l'utilisation de ce mot-clé, ainsi que plusieurs exemples.
S'il vous plaît expliquer avec un exemple. E.g. Prenez certains pays et déclare Comme Inde --State1 - Etat2 Australie --AusState1 --AusStae2 Je cherche la requête exacte –
L'exemple que je montrai, à l'adresse http://www.ibm.com/developerworks/db2/library/techarticle/dm-0510rielau/, donne la requête exacte - la copier ici semble inutile quand vous pouvez simplement cliquer sur le lien! -) –
** F ** section à [cette url] (https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql) était ce que je cherchais. –
Je n'ai pas utilisé de connexion auparavant, mais une recherche rapide montre qu'il est utilisé pour les structures arborescentes. Dans SQL Server, vous utilisez des expressions de table communes pour obtenir des fonctionnalités similaires.
Veuillez expliquer avec un exemple. E.g. Prenez certains pays et les États Comme Inde --State1 - Etat2 Australie --AusState1 --AusStae2 –
@Alex Martelli
La réponse est excellente! Mais il ne travailler que pour un élément à temps (WHERE name = 'Joan'
) Si vous prenez la clause WHERE
, la requête renverra toutes les lignes ensemble de racines ...
j'ai changé un peu pour ma situation, il peut montre l'arbre entier pour une table.
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: racine, 1: premier niveau après la racine, ...)
et la requête: devrait être quelque chose comme
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 le domaine level
, je ne juste faire plus lisible)
la réponse à cette requête:
J'espère que cela aide quelqu'un!
maintenant, je me demande comment faire sur MySQL ... ^^
j'ai eu un problème bizarre d'adapter votre code, avec un non les mêmes types de données sur le délimiteur et la colonne récursive .... mais il a trié, juste en définissant explicitement la première longueur .... merci pour l'aide! –
Est-il possible d'éviter la construction d'un chemin à partir d'une chaîne ('concatenador') pour obtenir une structure arborescente (donc chaque valeur de sous-feuille est regroupée sans trous par un autre élément)? Oracle 'connect by' construire de telle manière gratuitement. – gavenkoa
Puisque vous semblez vouloir plus de détails, vous devrez nous dire quelques données sur la structure de la table et ce que vous essayez de faire. Si vous avez une requête Oracle existante, ce serait un bon début ... –
@John, voir l'URL que j'ai posté dans ma réponse, http://www.ibm.com/developerworks/db2/library/techarticle/ dm-0510rielau/- il montre comment fonctionne CONNECT BY PRIOR (une syntaxe sympa mais réservée à Oracle pour obtenir des structures arborescentes) et comment obtenir le même effet avec des expressions de table communes (récursives), c'est-à-dire le mot clé WITH (qui est un standard SQL et implémenté dans IBM DB2, Microsoft SQL Server et le moteur PostgreSQL open-source dans la version 8.4). –
@Alex: merci, j'ai vu votre message et lu l'article. Très joli article, et je peux voir pourquoi les utilisateurs d'Oracle pourraient aimer la syntaxe Oracle. Je préfère la syntaxe standard, car elle est plus générale. –