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 :

Ajouter des conditions IF/ ELSE dans mysql


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 192
    Points : 68
    Points
    68
    Par défaut Ajouter des conditions IF/ ELSE dans mysql
    Bonjour à tous,

    J'aimerais calculer et afficher une moyenne seulement si une certaine condition s'applique. Pour faire simple je donne cette exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $sql="SELECT t.auteur_id, t.cours_id,"; 
    $sql.="CASE WHEN t.auteur_id ='3' THEN 'avg(t.score)' ELSE '' END ";
    $sql.="FROM Auteur t";
    Donc ici, j'aimerais afficher la moyenne d'un score seulement si auteur_id =3.

    Mais j'ai toujours une erreur de syntaxe que j'ignore comment régler.

    Merci pour votre aide.

  2. #2
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut
    Je vois pas trop pourquoi utiliser un 'case' alors que tu n'as qu'une seule condition.
    Je connais pas trop la syntaxe de ça ...
    Sinon, c'est expliqué là :http://dev.mysql.com/doc/refman/5.0/...functions.html

    A ta place, je tenterai un simple "IF(cond, then, else) "

    Mais quand on y pense, je vois pas trop le sens de ta requête :
    Supposons que l'on ait ça :
    Table auteur
    auteur_id | score
    ------------------
    1 | 4
    3 | 3
    2 | 16
    3 | 7
    ------------------

    Que devrait afficher ta requête ?
    Il te manque pas un truc genre group by par hasard...?

    De plus, ta question porte davantage sur du SQL que du PHP, donc je pense que tu t'aies trompé de forum...

  3. #3
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    salut,

    dans un select, tu peux utiliser la version fonctionnelle de if que te propose climoo... mais là ton approche est mauvaise, tu n'auras pas la moyenne... il faut faire un group by...

    pas la peine de surnommer ta table... non plus s'il n'y a qu'une table en jeu...

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT auteur_id, cours_id, avg(score)
    FROM Auteur
    group by auteur_id
    where auteur_id=3
    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 192
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par Climoo Voir le message
    Je vois pas trop pourquoi utiliser un 'case' alors que tu n'as qu'une seule condition.
    Je connais pas trop la syntaxe de ça ...
    Sinon, c'est expliqué là :http://dev.mysql.com/doc/refman/5.0/...functions.html

    A ta place, je tenterai un simple "IF(cond, then, else) "

    Mais quand on y pense, je vois pas trop le sens de ta requête :
    Supposons que l'on ait ça :
    Table auteur
    auteur_id | score
    ------------------
    1 | 4
    3 | 3
    2 | 16
    3 | 7
    ------------------

    Que devrait afficher ta requête ?

    De plus, ta question porte davantage sur du SQL que du PHP, donc je pense que tu t'aies trompé de forum...
    Ma requête devrait afficher 5 c'est à dire juste la moyenne de l'auteur avec id 3.

    Le forum s'intitule PHP & MySQL, donc je suis sans le forum j'imagine, non ?

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 192
    Points : 68
    Points
    68
    Par défaut Ajouter des conditions IF/ ELSE dans mysql
    ok, je vais donner un autre exemple qui peut être sera plus clair et va mieux expliquer mon besoin.

    J'ai la table suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    id    note1  note2  timestamp
    1     3        0        12 mars
    2     5        0        12 mars
    3     6        0        12 mars
    4     5        6        15 mars
    5     7        7        15 mars
    6     4        0        15 mars
    La colonne note2 a été ajouté dans la table le 15 mars. Quand j'ai ajouté la colonne note2, les 0 ont été ajoutés par défaut dans les dates avant le 15 mars, alors que c'est pas une vrai note qui doit être calculée dans la moyenne. Par contre le 0 de la note2 pour le id 6 est un vrai 0 car ca été ajouté à partir du 15 mars et doit être calculé dans la moyenne. Donc ce que je veux faire, c'est que la moyenne de la note2 se calcule à partir de 15 mars.

    Autrement-dit, je dois ajouter dans ma requête une syntaxe du genre: si le timestamp est plus grand ou égal au 15 mars on calcule la moyenne de la note2, sinon on prends pas cette note en considération

    J'espère que maintenant vous comprenez mieux mon besoin

  6. #6
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Bonjour,

    la structure de ta table est mauvaise et c'est la raison pour laquelle tu galères.
    Tu comptes rajouter des colonnes noteX autant de fois que nécessaire ?
    Si oui, cela va devenir vite ingérable.
    tu devrais plutôt faire ainsi :
    id | id_exam | id_eleve | note

    La date devrait être rattachée à l'examen et pas à la note.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 192
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    Bonjour,

    la structure de ta table est mauvaise et c'est la raison pour laquelle tu galères.
    Tu comptes rajouter des colonnes noteX autant de fois que nécessaire ?
    Si oui, cela va devenir vite ingérable.
    tu devrais plutôt faire ainsi :
    id | id_exam | id_eleve | note

    La date devrait être rattachée à l'examen et pas à la note.
    Bonjour Rawsrc,

    En effet, ton approche est bonne et je l'utilise déjà dans d'autres projets, mais j'ai pas le choix de travailler avec la structure qui est déjà en place et c'est pour ça que je dois trouver un moyen pour contourner ça.

    Non je ne comptes pas rajouter des colonnes noteX autant de fois que nécessaire, c'est seulement une fois et c'est une exception



    Merci

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Je pense que tu vas devoir calculer la moyenne à partir du 15 mars séparément et faire une union avec le reste.

    Donne la structure de la table, un petit jeu de données et le résultat attendu.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 192
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Je pense que tu vas devoir calculer la moyenne à partir du 15 mars séparément et faire une union avec le reste.
    En effet, c'est exactement ce que je veux faire.

    Voici ma table:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    id   auteur_id  note1  note2    timestamp
    1           3      7        0        12 mars
    2           5      8        0        12 mars
    3           6      5        0        12 mars
    4           5      6        6        15 mars
    5           7      3        7        15 mars
    6           5      6        0        15 mars
    Résultat attendu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Moyenne note1       Moyenne note2
             5 .83                      4.33
    Requête actuel:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT t.id, t.auteur_id, r2.Moyenne1,r2.Moyenne2
    FROM result t
    JOIN (SELECT r.auteur_id, avg(r.note1) as "Moyenne1",avg(r.note2) as "Moyenne2",
    FROM result r)r2;
    Avec cette requête j'obtiens une moyenne de 2.17 pour la note 2 alors que c'est pas le résultat souhaité

    Merci

  10. #10
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Update les note2 inférieures au 15 mars à NULL, modifie la structure des colonnes notes en DEFAULT NULL et lors d'une prochaine création de colonne précise DEFAULT NULL.

    Ensuite une simple requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select avg(note1), avg(note2) from la_table
    fera l'affaire car NULL n'est pas pris en compte par les fonctions d'aggrégations comme AVG ou SUM...

    Après ça reste de la bidouille, je rejoins totalement rawsrc sur le problème de modélisation de la table.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 192
    Points : 68
    Points
    68
    Par défaut
    Ok je vais essayer ca.Merci

  12. #12
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    j'espère que cette fois c'est la bonne structure définitive...

    n'oublie pas que les gens prennent sur leur temps pour réfléchir à ton problème et que prendre des pseudo exemple qui ne se ressemble pas du tout pour un même problème...

    à supposer qu'il ne peut donc y avoir que 2 dates possible sur l'ensemble de la table, alors en une seule requête pas optimisée pour beaucoup de lignes:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select avg(if((select max(timestamp) from la_table)>timestamp,note1,note2))
    from la_table

    le mieux est de faire une procédure stockée, pour ne pas ré-exécuter la sous requête à chaque fois:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    delimiter $$
    drop procedure moyenne$$
    create procedure moyenne()
    begin
      declare date a;
      select max(timestamp) into a from la_table;
      select avg(if(a>timestamp,note1,note2)) from la_table;
    end$$
    delimiter ;
     
    call moyenne();
    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 192
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Update les note2 inférieures au 15 mars à NULL, modifie la structure des colonnes notes en DEFAULT NULL et lors d'une prochaine création de colonne précise DEFAULT NULL.
    Ton approche à bien du sens et je vais opter pour car je trouve que c'est la meilleur solution qui réponds à mes besoins actuels.

    Des fois on a pas le choix de faire avec ce qu'on a déjà en place.

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2006
    Messages : 192
    Points : 68
    Points
    68
    Par défaut
    Merci à tous

Discussions similaires

  1. Ajouter des conditions dans une expression
    Par ruru9 dans le forum QlikView
    Réponses: 2
    Dernier message: 16/12/2013, 12h40
  2. condition sur count(*) dans mysql
    Par arizona_dream dans le forum Langage SQL
    Réponses: 4
    Dernier message: 25/09/2005, 09h06
  3. Récupérer des valeurs de checkbox dans MySQL
    Par digger dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 05/09/2005, 14h58
  4. [Fichier] Ajout des lignes de doc dans arraylist
    Par 3adoula dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 29/04/2004, 22h41

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