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 :

CASE + SUM() : problème de syntaxe ou cas non admis ?


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Septembre 2019
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Septembre 2019
    Messages : 27
    Points : 14
    Points
    14
    Par défaut CASE + SUM() : problème de syntaxe ou cas non admis ?
    Bonjour,

    J'en appelle aux bonnes âmes car je butte sur un requête combinant les clauses CASE et SUM.

    J'ai le message erreur suivant : SQL0120 - Utilisation de la fonction non admise.

    Je pense que c'est lié au


    Ci-dessous mon code :

    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
    19
    20
    Select id_personne,
     
         SUM ( CASE 
            WHEN code_operation in (100, 101, 102) and code_type = 'AAA' and year(horomain)= annee_saisie
            THEN coalesce(((sum(montantdebit)-sum(montantcredit))* count(distinct(numero_ordre))/count(numero_ordre)),0)
     
            END) AS "Resultat_1",
     
         SUM ( CASE 
            WHEN code_operation in (105,106) and code_type = 'AAA' and year(horomain)= annee_saisie
            THEN coalesce(((sum(montantdebit)-sum(montantcredit))* count(distinct(numero_ordre))/count(numero_ordre)),0)
     
            END) AS "Resultat_2",
     
     from matable1
     
     left join matable2 on ID_table1 = ID_table2
     
     groupe by  id_personne
     order by id_personne

    J'ai essayé aussi ainsi mais sans succès:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CASE (
            WHEN code_operation in (100, 101, 102) and code_type = 'AAA' and year(horomain)= annee_saisie
            THEN coalesce(((sum(montantdebit)-sum(montantcredit))* count(distinct(numero_ordre))/count(numero_ordre)),0)
     
            END) AS "Resultat_1",
    Merci par avance de votre aide ! )

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    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 080
    Points : 30 788
    Points
    30 788
    Par défaut
    Peut-être comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    coalesce(   (    sum(case when code_operation in (100, 101, 102) and code_type = 'AAA' and year(horomain)= annee_saisie then montantdebit end)
                -   sum(case when code_operation in (100, 101, 102) and code_type = 'AAA' and year(horomain)= annee_saisie then montantcredit end)
                )   *   count(distinct (case when code_operation in (100, 101, 102) and code_type = 'AAA' and year(horomain)= annee_saisie then numero_ordre end)) / 
                    (sum (case when code_operation in (100, 101, 102) and code_type = 'AAA' and year(horomain)= annee_saisie then 1 end))
                ,   0)
    Toutefois, en sachant de quelle table vient chaque colonne utilisée dans l'expression, il y a sans doute moyen de faire beaucoup plus simple.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Septembre 2019
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Septembre 2019
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Merci Al !

    Nonobstant une parenthèse en trop lol, ça marche impec ! )
    Un grand merci

    Pour répondre à ton interrogation, j'ai préfixé les champs et tables correspondantes. Au cas où il serait possible de faire plus simple...
    Cependant, ainsi, j'ai pu m'affranchir de faire des left joint à répétition sur la table t2 (au fait, autant que de famille de codes opération) et je gagne considérablement en performance.
    C'est pour cela que je voulais utiliser les clauses CASE et SUM mais avec du mal pour la syntaxe...

    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
     Select t3.id_personne,
    coalesce(   (    sum(case when t2.code_operation in (100, 101, 102) and t2.code_type = 'AAA' and t2.year(horomain)= t1.annee_saisie then t2.montantdebit end)
                -   sum(case when t2.code_operation in (100, 101, 102) and t2.code_type = 'AAA' and t2.year(horomain)= t1.annee_saisie then t2.montantcredit end)
                )   *   count(distinct (case when t2.code_operation in (100, 101, 102) and t2.code_type = 'AAA' and t2.year(horomain)= t1.annee_saisie then t2.numero_ordre end)) / 
                    (sum (case when t2.code_operation in (100, 101, 102) and t2.code_type = 'AAA' and t2.year(horomain)= t1.annee_saisie then 1 end)
                ,   0) as "Résultat 1" ...    
     
     
    from matable1 t1
     
    left join matable2 t2 on t1.ID_table1 = t2.ID_table2
    left join matable3 t3 on t2.ID_table2 = t3.ID_table3
     
    where t1.annee_saisie = 2018 and t1.categorie = 'XXX' 
     
    groupe by  t3.id_personne
    order by t3.id_personne
    J'aurai aimé ton avis sur ma dernière colonne Comme j'ai besoin dans une dernière colonne Total d'additionner tous les résultats intermédiaires (soit Total = Résultat 1 + Résultat 2..), j'ai agrégé tout simplement les requêtes soit : coalesce( ( sum(case when t2.code_operation in (100, 101, 102) and... , 0) + coalesce( ( sum(case when t2.code_operation in (105, 106) and... , 0) +... as "Total". Cela fonctionne bien sans obérer les performances ; car je crois que toutes les données (Résultats 1 ,Résultats 2...) sont déjà "stockées" dans une sorte de table temporaire non ?? Qu'en penses tu ?

    Encore un grand merci )

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    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 080
    Points : 30 788
    Points
    30 788
    Par défaut
    Et comme ça ?
    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
    select  t3.id_personne
        ,   coalesce((sum(t2.montantdebit) - sum(t2.montantcredit)) * count(distinct t2.numero_ordre) / sum(case when t2.ID_table1 is not null then 1 end), 0) as "Résultat 1" 
    from    matable1    t1
        left join 
            matable2    t2 
            on  t2.ID_table2        = t1.ID_table1
            and year(t2.horomain)   = t1.annee_saisie
            and t2.code_type        = 'AAA'
            and t2.code_operation   in (100, 101, 102)
        left join
            matable3    t3
            on  t2.ID_table2   = t3.ID_table3
    where   t1.annee_saisie = 2018
        and t1.categorie    = 'XXX' 
    group by t3.id_personne
    order by t3.id_personne
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Septembre 2019
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Septembre 2019
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Bonjour Al,

    Oui, cela fonctionne bien aussi avec ce code.

    Il ressemble presque en tout point à mon code d'origine, mis à part la fin du code mise en gras
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    coalesce((sum(t2.montantdebit) - sum(t2.montantcredit)) * count(distinct t2.numero_ordre) / sum(case when t2.ID_table1 is not null then 1 end), 0) as "Résultat 1"
    Après, cette syntaxe me pose un gros problème de perf car la requête, compte tenu du volume des données traitées et des jointures répétées devient trop lourde à l'exécution, voir plante ;
    Je dois en effet dans cette syntaxe créer autant de jointures sur la table T2 que de "groupes" de code opérations traités et j'ai en tout près de 70 000 lignes attendues en résultat.
    C'est pourquoi je voulais utiliser la clause CASE, cela m'affranchit des jointures répétées. Et avec ta syntaxe, c'est top

    Cela donnerait ça en gros :

    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
    select 
    t3.id_personne
    , coalesce((sum(t2.A.montantdebit) - sum(t2.A..montantcredit)) * count(distinct t2.A.numero_ordre) / sum(case when t2.A.ID_table2 is not null then 1 end), 0) as "Résultat 1" 
    , coalesce((sum(t2.B.montantdebit) - sum(t2.B.montantcredit)) * count(distinct t2.B.numero_ordre) / sum(case when t2.B.ID_table1 is not null then 1 end), 0) as "Résultat 2" 
    , coalesce((sum(t2.C.montantdebit) - sum(t2.C.montantcredit)) * count(distinct t2.C.numero_ordre) / sum(case when t2.C.ID_table1 is not null then 1 end), 0) as "Résultat 3" ...
     
    from   matable1  t1
        left join matable2  t2 A  on  t2.A.ID_table2 = t1.ID_table1  and  year(t2.A.horomain) =  t1.annee_saisie  and  t2.A.code_type = 'AAA'   and  t2.A.code_operation  in (100, 101, 102)
        left join matable2  t2 B  on  t2.B.ID_table2 = t1.ID_table1  and  year(t2.B.horomain)  =  t1.annee_saisie  and  t2.B.code_type = 'AAA'   and  t2.B.code_operation  in (105, 106)
        left join matable2  t2 A  on  t2.C.ID_table2 = t1.ID_table1  and  year(t2.C.horomain) =  t1.annee_saisie  and  t2.C.code_type = 'AAA'   and  t2.C.code_operation  in (107, 108, 109, 110, 111) ...
     
       left join matable3  t3 on  t2.ID_table2 = t3.ID_table3
     
       where  t1.annee_saisie = 2018 and t1.categorie    = 'XXX' 
     
    group by t3.id_personne
    order by t3.id_personne

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

Discussions similaires

  1. Problème de syntaxe avec CASE WHEN
    Par Lord_Chesseling dans le forum Langage SQL
    Réponses: 17
    Dernier message: 26/01/2015, 21h08
  2. Problème de syntaxe non identifié
    Par Zaltymbunk dans le forum MATLAB
    Réponses: 0
    Dernier message: 31/12/2010, 14h07
  3. Problème de syntaxe sur la division non arrondie de deux variables
    Par fuyo2004 dans le forum Général Python
    Réponses: 2
    Dernier message: 28/05/2010, 17h27
  4. problème de syntaxe pour select case
    Par bddaccess dans le forum VBA Access
    Réponses: 23
    Dernier message: 23/09/2008, 11h24
  5. Problème de syntaxe d'un CASE dans un WHERE?
    Par Danny Blue dans le forum Langage SQL
    Réponses: 4
    Dernier message: 05/04/2007, 23h18

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