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

Développement SQL Server Discussion :

INNER JOIN sur une valeur minimale


Sujet :

Développement SQL Server

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Points : 131
    Points
    131
    Par défaut INNER JOIN sur une valeur minimale
    Bonjour,

    J'ai deux tables. Une table Group et une table Event.

    Un Event est en relation avec un Group et dispose d'une Date. Un Group peut être en relation avec plusieur Event sous la seul contrainte que la Date soit unique.
    Un Event a une EndDate qui est calculé en fonction de la Date de l'event suivant. Un Event prend fin dès qu'un autre du même Group débute.

    J'aimerais faire un UPDATE qui me met à jour la EndDate de tout mes Event.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    GROUPE G1
        EVENT V10 01/01/2015
        EVENT V11 03/01/2015
        EVENT V12 05/01/2015
     
    GROUPE G2
        EVENT V20 01/01/2015
        EVENT V21 03/01/2015
    Pour le moment, je suis arrivé à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    UPDATE V1
    SET T1.EndDate = T2.Date
    FROM Event Event T1
    INNER JOIN Event T2
    ON T1.Group_Id = T2.Group_Id
    AND T1.Date < T2.Date
    La jointure me donnerais les résultats suivants :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    V10 - V11
    V10 - V12
    V11 - V12
    V20 - V21
    Et je cherche à avoir pour chaque Event uniquement la jointure avec la Date la plus petite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    V10 - V11
    V11 - V12
    V20 - V21
    J'avais l'idée de faire un ORDER BY sur la date de la table jointe et de faire un Distinct sur l'id de l'Event mais je n'arrive à rien pondre de syntaxiquement correcte.

    Help.

    Edit : Résolu =)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    UPDATE A1 
    SET A1.DateFin = A2.MinDateFin
    FROM Event A1 
    INNER JOIN (
    	SELECT B1.Id, MIN(B2.DateFin) AS MinDateFin
    	FROM Event B1 
    	INNER JOIN (
    		SELECT C1.Id, C2.Date AS DateFin
    		FROM Event C1
    			INNER JOIN Event C2
    		ON C1.Groupt_Id = C2.Group_Id
    			AND C1.DateEffet < C2.DateEffet
    		) B2
    	ON B1.Id = B2.Id
    	GROUP BY B1.Id
    	) A2
    ON A1.Id = A2.Id

  2. #2
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    En plus simple, et certainement plus rapide :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select e1.*
    from evt e1
    inner join evt e2 on e2.groupe = e1.groupe and e2.moment < e1.moment
    left outer join evt e3 on e3.groupe = e2.groupe and e3.moment < e2.moment
    where e3.nom is null;

    On fait une première auto-jointure pour retrouver les éléments précédents.
    Et une seconde auto-jointures pour retrouver les éléments précédents aux éléments précédentes.

    Et on ne retient que les éléments précédents qui n'ont pas eux-même de précédent.
    On ne jouit bien que de ce qu’on partage.

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Points : 131
    Points
    131
    Par défaut
    Si on reprend mon exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    GROUPE G1
        EVENT V10 01/01/2015
        EVENT V11 03/01/2015
        EVENT V12 05/01/2015
     
    GROUPE G2
        EVENT V20 01/01/2015
        EVENT V21 03/01/2015
    select e1.*
    from evt e1
    inner join evt e2 on e2.groupe = e1.groupe and e2.moment < e1.moment
    left outer join evt e3 on e3.groupe = e2.groupe and e3.moment < e2.moment
    where e3.nom is null;

    La première jointure donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    e1   - e2
     
    V11 - V10
    V12 - V10
    V12 - V11
    V21 - V20
    La seconde donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    e1   - e2   - e3
     
    V11 - V10 - NULL
    V12 - V10 - NULL
    V12 - V11 - V10
    V21 - V20 - NULL
    Et si on se réduit au ligne ou les précédents n'ont pas de précédents :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    e1   - e2   - e3
     
    V11 - V10 - NULL
    V12 - V10 - NULL
    V21 - V20 - NULL
    Alors que je voudrais des couples qui se suivent directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    e1   - e2
     
    V11 - V10
    V12 - V11
    V21 - V20

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    sinon, une solution comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    WITH CTE AS (
    	SELECT 
    			fin
    		,	LEAD(debut) OVER(PARTITION BY groupe_id ORDER BY debut) as tmp
    	FROM Event
    )
    UPDATE CTE 
    	SET fin = tmp

  5. #5
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Points : 131
    Points
    131
    Par défaut
    Jolie, sexy, parfait. Dommage que je développe pour du sql server 2008.

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    il est néanmoins possible "d'émuler" LEAD avec ROW_NUMBER (qui est dispo sous 2008).

    Un exemple ici

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Deux inner join sur une même table
    Par Pachina75 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 04/06/2014, 14h54
  2. Requete avec inner join sur une meme table
    Par mattmax dans le forum Développement
    Réponses: 1
    Dernier message: 15/12/2011, 14h34
  3. deux inner join sur une table
    Par the-player777 dans le forum Requêtes
    Réponses: 2
    Dernier message: 05/11/2007, 09h43
  4. INNER JOIN sur une requete UPDATE
    Par Immobilis dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 06/03/2006, 14h05
  5. [XSL]appliquer la fonction substring sur une valeur récupéré
    Par totoranky dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 22/02/2006, 17h21

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