Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 19/01/2012, 10h03   #1
Membre régulier
 
Inscription : juin 2008
Messages : 117
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 117
Points : 88
Points : 88
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 :
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 :
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 :
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 ?
bilbot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2012, 11h20   #2
Membre du Club
 
Inscription : juin 2007
Messages : 115
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 115
Points : 41
Points : 41
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...
azur668 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2012, 13h41   #3
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Essayez ainsi :
Code :
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)
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2012, 14h12   #4
Membre régulier
 
Inscription : juin 2008
Messages : 117
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 117
Points : 88
Points : 88
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...
bilbot est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h28.


 
 
 
 
Partenaires

Hébergement Web