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

Requêtes et SQL. Discussion :

Erreur bizarre d'une sous-requête dans une requête principale avec regroupement [AC-2003]


Sujet :

Requêtes et SQL.

  1. #1
    FMJ
    FMJ est déconnecté
    Membre averti
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    416
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 416
    Points : 363
    Points
    363
    Par défaut Erreur bizarre d'une sous-requête dans une requête principale avec regroupement
    Salut,

    Je ne comprenais pas le pourquoi d'une erreur d'exécution d'une requête mais je pense être tombé sur la cause.

    Soit la table1 qui a deux champs
    > Date1 de type Date
    > Valeur1 de type réel simple
    et la table2 qui a deux champs
    > Date2 de type Date
    > Valeur2 de type réel simple


    La requête suivante passe très bien avec jet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT date1, SUM(valeur1) AS A, 
    (SELECT SUM(valeur2) FROM table2 WHERE YEAR(date2)=YEAR(date1)) AS B
    FROM table1
    GROUP BY date1
    Par contre, la requête suivante plante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT YEAR(date1), SUM(valeur1) AS A, 
    (SELECT SUM'valeur2) FROM table2 WHERE YEAR(date2)=YEAR(date1)) AS B
    FROM table1
    GROUP BY YEAR(date1)
    avec l'erreur "Vous avez essayé d'exécuter une requête ne comprenant pas l'expression spécifiée 'date1' comme une partie de la fonction d'agrégat"

    Bref, quand on utilise un champ de la requête principal dans une requête secondaire, il faut que ce champ fasse partie individuellement du GROUP BY (et s'il fait partie seulement d'une expression du GROUP BY, ça ne marche pas !).

    (Et bien entendu, utiliser une jointure ne permet pas d'arriver au résultat attendu)

    Vous aviez déjà constaté cette limitation (qui n'existe pas en Transac SQL) ?

  2. #2
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Bonjour,

    Outre le fait que je n'ai rencontré aucune difficulté avec votre requête, celle ci me semble plus adaptée et plus performante :

    Code sql : 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
    19
    20
    21
    SELECT 
      Y1, A, B
    FROM
      (
        SELECT 
          Year(Date1) AS Y1, Sum(valeur1) as A 
        FROM
          Table1
        GROUP BY Year(Date1)
      ) T1
     
      INNER JOIN
      (
        SELECT 
          Year(Date2) AS Y2, Sum(valeur2) as B 
        FROM
          Table2
        GROUP BY Year(Date2)
      ) T2
      ON  T1.Y1=T2.Y2
    GROUP BY Y1,A,B

  3. #3
    FMJ
    FMJ est déconnecté
    Membre averti
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    416
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 416
    Points : 363
    Points
    363
    Par défaut
    Bonjour Tofalou,

    Oui c'est étrange, je viens de tester le cas présenté ci-dessus et celui-ci ne génère pas l'erreur (j'aurais dû vérifier avant ! ).
    Pourtant, c'est juste une version simplifiée des tables et de la requête utilisée réellement. Et, dans la "vraie" requête, lorsque je change l'équivalent de "SELECT YEAR(date1)" par "SELECT date1", l'erreur disparaît (sans rien toucher d'autre, notamment dans la sous-requête).

    Quant à ta proposition de jointure, on peut effectivement réécrire la requête de plusieurs façons. J'avais d'ailleurs penser à un moment utiliser plutôt un UNION.
    Mais le problème, c'est qu'avec 26 colonnes dans la requête principale, dont la plupart ne sont pas directement calculables avec une fonction d'agrégation de la requête principale :
    • soit on utilise comme proposé des jointures ou des UNION mais l'écriture, la lisibilité et la maintenance vont être être sacrément compliquées

    • soit on passe par des sous-requêtes, ce qui me permet de gagner énormément en clarté, en traitant isolément chaque colonne (mais on y permet en perf, c'est vrai)


    Bon je retourne à ma requête pour essayer de comprendre ce qui cloche.

    Merci

  4. #4
    FMJ
    FMJ est déconnecté
    Membre averti
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    416
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 416
    Points : 363
    Points
    363
    Par défaut
    Autant pour moi, je suis le rois des c..

    J'ai trop schématisé ma requête. Or, en la réanalysant l'originale, je me suis aperçu que j'utilisais une expression dans la sous-requête qui n'était pas l'identique de celle utilisée dans le regroupement de la requête principale. Et là bien sûr, SQL n'aime pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT expression1(date1), SUM(val1), 
    (SELECT SUM(val2) FROM table2 WHERE date2=expression2(date1)  )
    FROM table1
    GROUP BY expression1(date1)
    expression2(date1), différent de expression1(date1), ne se trouve pas dans le GROUP BY, d'où message d'erreur portant sur le champ date1.

    Désolé pour le dérangement

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 13/11/2009, 16h06
  2. Réponses: 28
    Dernier message: 22/09/2005, 11h57
  3. je cherche une sous chaine dans une chaine
    Par avprive dans le forum C++
    Réponses: 3
    Dernier message: 17/03/2005, 01h48
  4. Rechercher une sous chaine dans une chaine
    Par annedjomo dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 04/02/2005, 10h36
  5. Rechercher une sous chaine dans une chaine
    Par Oluha dans le forum ASP
    Réponses: 4
    Dernier message: 03/02/2005, 14h39

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