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

Langage SQL Discussion :

Requête UPDATE en prenant la somme des enregistrements précédents


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Homme Profil pro
    Technicien informatique
    Inscrit en
    Mai 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mai 2014
    Messages : 7
    Points : 4
    Points
    4
    Par défaut Requête UPDATE en prenant la somme des enregistrements précédents
    Bonjour à tous,

    J'ai la table suivante:

    Date1	TempsTotal	TempsRestant	ReportTempsRestantJoursPrec
    02/05/2014	1.23	NULL	NULL
    09/05/2014	81.17	50	NULL
    12/05/2014	24.67	3.17	NULL
    13/05/2014	44.45	4.45	NULL
    14/05/2014	12.27	1.85	NULL
    15/05/2014	20.12	NULL	NULL
    ...
    Pour chaque enregistrement, je souhaite mettre à jour la colonne 'ReportTempsRestantJoursPrec' en y insérant la somme de la colonne TempsRestant des enregistrements précédents.
    Concrètement,
    pour la ligne 1, ReportTempsRestantJoursPrec doit être égal à 0 (c'est le 1er enregistrements de la table)
    pour la ligne 2, ReportTempsRestantJoursPrec doit être égal à 0
    pour la ligne 3, ReportTempsRestantJoursPrec doit être égal à 50
    pour la ligne 4, ReportTempsRestantJoursPrec doit être égal à 53.17
    pour la ligne 5, ReportTempsRestantJoursPrec doit être égal à 57.62
    pour la ligne 6, ReportTempsRestantJoursPrec doit être égal à 59.47
    ...

    Je pensais pouvoir m'en sortir en exécutant la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Update @TEMP1 SET ReportTempsRestantJoursPrec = (select Sum(T0.TempsRestant) from @TEMP1 T0 where T0.Date1 <= @TEMP.Date1 group by T0.Date1 order by T0.Date1)
    Mais SQL me renvoie l'erreur suivante:
    La clause ORDER BY n'est pas valide dans les vues, les fonctions inline, les tables dérivées, les sous-requêtes et les expressions de table communes, sauf si TOP ou FOR XML est également spécifié.
    Je dois mal m'y prendre, quelqu'un saurait-il éclairer ma lanterne ??

    D'avance merci.

    Guillaume

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 103
    Points : 28 393
    Points
    28 393
    Par défaut
    La question à se poser est la suivante :
    Quelle est l'utilité des clauses GROUP BY et ORDER BY dans la sous-requête ?

  3. #3
    Candidat au Club
    Homme Profil pro
    Technicien informatique
    Inscrit en
    Mai 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mai 2014
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Bonjour al1_24,
    En effet, les clauses GROUP BY et ORDER BY sont inutiles.

    Voici la nouvelle requête:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Update @TEMP1 SET ReportTempsRestantJoursPrec = (select Sum(T0.TempsRestant) from @TEMP1 T0 where T0.Date1 <= @TEMP1.Date1)
    Cependant, SQL n'est toujours pas d'accord. Voici le message d'erreur : La variable scalaire "@TEMP1" doit être déclarée.
    Note : @TEMP1 est une table temporaire.

    Note : j'envisage bien une solution en faisant une boucle pour faire l'UPDATE de chaque enregistrement mais les boucles ne sont pas conseillées en SQL.
    C'est pour cela que je m'obstine à faire un UPDATE 'simple'.

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 103
    Points : 28 393
    Points
    28 393
    Par défaut
    @TEMP1 est une variable qui contient le nom de la table à mettre à jour ou est-ce une notation spécifique à ton SGBD (que tu n'as pas précisé) pour désigner une table temporaire ?

  5. #5
    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
    Citation Envoyé par Guillaume777 Voir le message

    Cependant, SQL n'est toujours pas d'accord. Voici le message d'erreur : La variable scalaire "@TEMP1" doit être déclarée.
    Note : @TEMP1 est une table temporaire.
    Visiblement, ce n'est pas l'avis de votre SGBDR (quel est-il) ?
    Comment avez-vous déclaré cette table temporaire ? pouvez nous nous montrer le script complet ?

  6. #6
    Candidat au Club
    Homme Profil pro
    Technicien informatique
    Inscrit en
    Mai 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mai 2014
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    @TEMP1 est une variable qui contient le nom de la table à mettre à jour ou est-ce une notation spécifique à ton SGBD (que tu n'as pas précisé) pour désigner une table temporaire ?

    mon SGBDR est SQL Server 2008 R2.
    @TEMP1 est le nom de la table temporaire que j'ai déclaré.

  7. #7
    Candidat au Club
    Homme Profil pro
    Technicien informatique
    Inscrit en
    Mai 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mai 2014
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Bonjour


    Visiblement, ce n'est pas l'avis de votre SGBDR (quel est-il) ?
    Comment avez-vous déclaré cette table temporaire ? pouvez nous nous montrer le script complet ?
    Je travaille sur SQL Server 2008 R2.


    J'ai une 1ère table temporaire @TEMP qui contient des données.
    J'extrais des données de cette table pour les ranger dans une 2ème table temporaire @TEMP1.
    Sur cette 2ème table, je souhaite faire la mise à jour de la colonne ReportTempsRestantJoursPrec comme expliqué précédemment.

    Ci-après le script:

    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
     
    DECLARE @TEMP1 AS TABLE 
    	(Date1 DATETIME, NB_OF INTEGER, NombreVerins INTEGER,  RatioTempsParVerin DECIMAL(19,2), TempsTotal DECIMAL(19,2), 
    	 TempsEffectue DECIMAL(19,2), TempsRestant DECIMAL(19,2),
    	 ReportTempsRestantJoursPrec DECIMAL(19,2), JourCourant CHAR)
     
     
    INSERT INTO @TEMP1 (Date1, NB_OF, NombreVerins, RatioTempsParVerin, TempsTotal, TempsEffectue, TempsRestant, ReportTempsRestantJoursPrec)
    select Date1, SUM(NB_OF), SUM(NombreVerins), SUM(RatioTempsParVerin), SUM(TempsTotal), SUM(TempsEffectue), SUM(TempsRestant), SUM(ReportTempsRestantJoursPrec)
    FROM @TEMP 
    group by Date1 order by Date1
     
     
     
    Update @TEMP1 SET ReportTempsRestantJoursPrec = (select Sum(T0.TempsRestant) from @TEMP1 T0 where T0.Date1 <= @TEMP1.Date1)

    Merci pour votre aide.
    Guillaume

  8. #8
    Candidat au Club
    Homme Profil pro
    Technicien informatique
    Inscrit en
    Mai 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mai 2014
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    OK, merci pour le tuyau, j'explore cette piste et te tiens informé.

  9. #9
    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
    Citation Envoyé par Guillaume777 Voir le message
    Je travaille sur SQL Server 2008 R2.
    Dommage, à partir de 2012 vous auriez pu faire directement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ;WITH CTE AS (
    	SELECT 
    		ReportTempsRestantJoursPrec
    		,SUM(TempsRestant) OVER(ORDER BY Date1) AS R
    	FROM @TEMP1
    )
    UPDATE CTE 
    	SET ReportTempsRestantJoursPrec = R
    Votre message vient de l'utilisation de @TEMP1 dans la clause WHERE. Donnez un alias à votre variable table.

    Cependant, vous pourriez carrément vous en passer a priori... Qu'en faites-vous ensuite ?

  10. #10
    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
    En fait, vous pouvez même faire plus simple, si vous gardez votre table temporaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    DECLARE @x DECIMAL (19,9)
     
    UPDATE A
    	SET @x 
    		= ReportTempsRestantJoursPrec 
    			=	COALESCE(ReportTempsRestantJoursPrec, 0) 
    				+ COALESCE(@x, 0) 
    				+ COALESCE(A.TempsRestant, 0) 
    FROM @TEMP1 A

  11. #11
    Candidat au Club
    Homme Profil pro
    Technicien informatique
    Inscrit en
    Mai 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mai 2014
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    En fait, vous pouvez même faire plus simple, si vous gardez votre table temporaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    DECLARE @x DECIMAL (19,9)
     
    UPDATE A
    	SET @x 
    		= ReportTempsRestantJoursPrec 
    			=	COALESCE(ReportTempsRestantJoursPrec, 0) 
    				+ COALESCE(@x, 0) 
    				+ COALESCE(A.TempsRestant, 0) 
    FROM @TEMP1 A

    Merci à aieeeuuuuu et al1_24 pour le coup de pouce.
    La solution de aieeeuuuuu fonctionne à merveille.
    Au passage, j'ai découvert la fonction COALESCE que je ne connaissais pas.

    Merci encore et bonne fin de journée.

  12. #12
    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
    Citation Envoyé par Guillaume777 Voir le message
    Note : j'envisage bien une solution en faisant une boucle pour faire l'UPDATE de chaque enregistrement mais les boucles ne sont pas conseillées en SQL.
    C'est pour cela que je m'obstine à faire un UPDATE 'simple'.
    C'est vrai, mais ça l'est également pour les variables tables.

    Notez que lorsque SQL Server génère un plan d’exécution pour une requête contenant une (ou plusieurs) variable table, il considère que celle-ci ne contient qu'une ligne, ce qui peut parfois biaiser fortement le calcul du plan d’exécution.

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

Discussions similaires

  1. Requête pour ecart de date entre des enregistrements successifs
    Par BB72650 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 20/05/2012, 11h55
  2. Réponses: 2
    Dernier message: 13/03/2012, 10h16
  3. Faire la somme des enregistrements dans un Etat
    Par afatdz dans le forum Bases de données
    Réponses: 3
    Dernier message: 23/04/2008, 15h13
  4. Somme des enregistrements d'une requête
    Par manu971 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 19/10/2007, 14h35
  5. somme des enregistrement d'un champ
    Par rostomides dans le forum Bases de données
    Réponses: 5
    Dernier message: 07/04/2006, 19h09

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