IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MS SQL Server Discussion :

Utilisation CTE récursives (Regroupement - éléments père <> éléments frère)


Sujet :

MS SQL Server

  1. #1
    Membre averti

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Points : 351
    Points
    351
    Par défaut Utilisation CTE récursives (Regroupement - éléments père <> éléments frère)
    Bonjour,
    Pour faire simple, voilà une série de données :
    Logement Rattachement
    A | B
    B | C
    C | D
    D | B
    E | A
    F | D
    G | F
    H | B
    J | K
    K | L
    L | J

    Je veux pouvoir indiquer quels sont les groupes de Logement, à savoir ici d'un coté A, B, C, D, E, F, G et H puis d'un autre J, K et L.
    Le problème est que l'élément père est parfois le frère d'un autre et vice versa. Par exemple on sait que A et C sont du même groupe car A est rattaché à B et B est rattaché à C, etc

    Si vous avez une idée, elle est la bienvenue
    Merci

    le script pour les tests (sous MS SQL 2005) :
    WITH TMP AS (SELECT 'A' AS Logement, 'B' AS Rattachement UNION SELECT 'B' AS Logement, 'C' AS Rattachement
    UNION SELECT 'C' AS Logement, 'D' AS Rattachement UNION SELECT 'D' AS Logement, 'B' AS Rattachement
    UNION SELECT 'E' AS Logement, 'A' AS Rattachement UNION SELECT 'F' AS Logement, 'D' AS Rattachement
    UNION SELECT 'G' AS Logement, 'F' AS Rattachement UNION SELECT 'H' AS Logement, 'B' AS Rattachement
    UNION SELECT 'J' AS Logement, 'K' AS Rattachement UNION SELECT 'K' AS Logement, 'L' AS Rattachement
    UNION SELECT 'L' AS Logement, 'J' AS Rattachement)

    SELECT *
    FROM TMP

  2. #2
    Membre averti

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Points : 351
    Points
    351
    Par défaut CTE récursives
    Après réflexion et quelques recherches il faut je pense utiliser les CTE récursives car on ne sait pas à l'avance combien de niveau il faut passer. Ici on va par exemple lier A à C car A est lié à B qui est lié lui même à C (là ça fait un niveau) mais pour F on va le lier à A car F est lié à D qui est lié à B qui est lié à A (là ça fait deux niveaux mais il peut y en avoir beaucoup plus).

    J'essaie de trouver mais toutes aides est la bienvenue.
    Merci

  3. #3
    Membre averti

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Points : 351
    Points
    351
    Par défaut comment écrire la CTE récursive
    J'avance peu à peu mais ce n'est pas encore cela. Si on voulait faire cela sous forme de requêtes classiques il faudrait écrire :

    WITH TMP1 AS ( SELECT Logement, Rattachement FROM TEST_01
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TEST_01 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    ,TMP2 AS ( SELECT Logement, Rattachement FROM TMP1
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TMP1 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    ,TMP3 AS ( SELECT Logement, Rattachement FROM TMP2
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TMP2 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    ,TMP4 AS ( SELECT Logement, Rattachement FROM TMP3
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TMP3 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    ,TMP5 AS ( SELECT Logement, Rattachement FROM TMP4
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TMP4 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    SELECT * FROM TMP5

    mais on a le problème de la profondeur des différents niveaux qui est inconnu.
    J'en reviens donc à la CTE récursive, je suis certain maintenant que la solution est là mais je n'arrive pas à écrire le script, pour le moment je m'arrête ici mais cela ne fonctionne pas :

    WITH tree (Logement, Rattachement)
    AS (SELECT Logement, Rattachement FROM TEST_01
    UNION ALL
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TEST_01 AS TAB1
    INNER JOIN tree AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    SELECT TOP 20 * FROM tree

    Si quelqu'un connait bien cette forme de requête, il est le bienvenue.
    Merci

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 848
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 848
    Points : 52 966
    Points
    52 966
    Billets dans le blog
    6
    Par défaut
    Donnez nous un exemple du résultat que vous voulez obtenir ainsi qu'un jeu d'essais sous la forme CREATE TABLE (DDLE) et INSERT.

    En cela vous vous conformerez à la charte de postage....
    http://www.developpez.net/forums/d96...vement-poster/

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Membre averti

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Points : 351
    Points
    351
    Par défaut
    -- création de la table
    CREATE TABLE [TEST_02]([
    Logement] [varchar](1) NOT NULL,
    [Rattachement] [varchar](1) NOT NULL
    ) ON [PRIMARY]

    -- ajout des données
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('A','B')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('B','C')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('C','D')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('D','B')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('E','A')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('F','D')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('G','F')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('H','B')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('J','K')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('K','L')
    INSERT INTO [TEST_02] ([Logement],[Rattachement]) VALUES ('L','J')

    -- résultat recherché
    WITH TMP1 AS ( SELECT Logement, Rattachement FROM TEST_01
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TEST_01 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    ,TMP2 AS ( SELECT Logement, Rattachement FROM TMP1
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TMP1 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    ,TMP3 AS ( SELECT Logement, Rattachement FROM TMP2
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TMP2 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    ,TMP4 AS ( SELECT Logement, Rattachement FROM TMP3
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TMP3 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    ,TMP5 AS ( SELECT Logement, Rattachement FROM TMP4
    UNION
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TMP4 AS TAB1 INNER JOIN TEST_01 AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    SELECT * FROM TMP5

    -- script de test avec une CTE récursive (ne fonctionne pas)
    WITH tree (Logement, Rattachement)
    AS (SELECT Logement, Rattachement FROM TEST_01
    UNION ALL
    SELECT TAB1.Logement, TAB2.Logement AS Rattachement FROM TEST_01 AS TAB1
    INNER JOIN tree AS TAB2 ON TAB2.Rattachement = TAB1.Rattachement )

    SELECT TOP 20 * FROM tree

    Si quelqu'un sait comment écrire la CTE récursive il est le bienvenue.
    Merci

Discussions similaires

  1. [2K8] Utilisation Matrix et regroupement
    Par spezet29 dans le forum SSRS
    Réponses: 0
    Dernier message: 06/01/2011, 11h55
  2. recuperation d'éléments pères depuis une iframe servlet
    Par progamer54 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 21/01/2009, 11h38
  3. Réponses: 8
    Dernier message: 23/09/2007, 19h40
  4. Réponses: 4
    Dernier message: 26/05/2005, 17h46
  5. Réponses: 7
    Dernier message: 07/09/2004, 14h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo