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 :

UPDATE avec Jointure, clause GROUP BY et HAVING


Sujet :

Développement SQL Server

  1. #1
    Membre averti

    Inscrit en
    Juin 2008
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 307
    Points : 364
    Points
    364
    Par défaut UPDATE avec Jointure, clause GROUP BY et HAVING
    Je vous explique mon problème :

    J'ai 2 tables TableA et TableS. TableS est la table dans laquelle je dois mettre le champs FLD024 à jour suivant un critère de comptage dans la table B.

    Voici la requête de sélection qui me permet de savoir quelles lignes vont être MAJ :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT S.FLD000, SUM(A.NbLect), SUM(A.NbLien)
    FROM TableS S INNER JOIN TableA A ON S.FLD000 = A.FLD000
    WHERE DATEDIFF(DAY,A.DateGen, GETDATE()) <= 30 
    AND (S.FLD024 <> 0 OR S.FLD024 IS NULL )
    GROUP BY A.FLD000
    HAVING SUM(A.NbLect) < 2 AND SUM(A.NbLien) < 6
    FLD000 c'est ma clef primaire


    Je souhaite transformer cette requête pour faire l'update du champ FLD024 en intégrant directement la jointure. Je sais que je pourrais utiliser la requête ci dessus comme une sous requête, mais je me dit qu'en faisant une jointure ca sera plus rapide. J'ai essayé différentes combinaisons qui ne fonctionnent sans succès :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UPDATE TableS 
    SET FLD024 = 0, FLD023 = GETDATE()
    FROM TableS S
    INNER JOIN TableA A ON S.FLD000 = A.FLD000
    WHERE DATEDIFF(DAY,A.DateGen, GETDATE()) <= 30  
    AND (S.FLD024 <> 0 OR S.FLD024 IS NULL ) 
    GROUP BY FLD000 
    HAVING SUM(A.NbLect) < 2 AND SUM(A.Nblien) < 6
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    UPDATE TableS S INNER JOIN TableA A ON S.FLD000 = A.FLD000
    SET S.FLD024 = 0, S.FLD023 = GETDATE()
    WHERE DATEDIFF(DAY,A.DateGen, GETDATE()) <= 30
    AND (S.FLD024 <> 0 OR S.FLD024 IS NULL )
    GROUP BY S.FLD000
    HAVING SUM(A.NbLect) < 2 AND SUM(A.NbLien) < 6
    j'avoue que je calle surcomment construire cette requête et je me dit qu'on peut pas faire comme cela.

    Qu'en pensez vous ?

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par bilbot Voir le message
    mais je me dit qu'en faisant une jointure ca sera plus rapide.
    Je ne pense pas qu'il y ai de différence notable. Et si oui, probablement insignifiante.
    Pas la peine de complexifier le code pour ça (sauf si de très grands volumes de données sont traités à chaque exécution de la requête)

    Citation Envoyé par SQLpro
    http://sqlpro.developpez.com/cours/sqlaz/sousrequetes/
    En général les performances seront meilleures en utilisant une jointure que dans le cas d'une sous-requête avec [NOT] IN.
    j'en déduit que pour les autres types de sous-requetes il n'y a pas de différence.
    Mais de toute façons SQLpro ne va pas tarder à rappliquer pour donner son avis...

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Essayez ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    UPDATE TABLES
       SET FLD024 = 0
         , FLD023 = GETDATE()
     WHERE FLD000 IN (SELECT S.FLD000
                        FROM TABLES AS S
                             INNER JOIN TableA A
                               ON S.FLD000 = A.FLD000
                       WHERE DATEDIFF(DAY,A.DateGen, GETDATE()) <= 30  
                         AND (S.FLD024 <> 0 OR S.FLD024 IS NULL )
                    GROUP BY FLD000 
                      HAVING SUM(A.NbLect) < 2
                         AND SUM(A.Nblien) < 6)

  4. #4
    Membre averti

    Inscrit en
    Juin 2008
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 307
    Points : 364
    Points
    364
    Par défaut
    Oui ca c'est la version avec sous requête. Elle marche mais je pense qu'on peut mieux faire en intégrant la jointure dans l'update...

Discussions similaires

  1. Update avec la clause having
    Par ahbari dans le forum Développement
    Réponses: 2
    Dernier message: 22/04/2015, 22h56
  2. Réponses: 16
    Dernier message: 20/01/2011, 12h45
  3. Update avec jointure et group by
    Par olibara dans le forum Langage SQL
    Réponses: 2
    Dernier message: 27/11/2010, 10h18
  4. Requête SQL - Pb avec la clause GROUP BY
    Par jeromesco dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 10/07/2006, 09h04
  5. [PL/SQL] update avec jointure
    Par Fox_magic dans le forum Oracle
    Réponses: 6
    Dernier message: 09/12/2004, 12h19

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