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

SQL Procédural MySQL Discussion :

opération sur des champs déjà manipulés


Sujet :

SQL Procédural MySQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 30
    Points : 22
    Points
    22
    Par défaut opération sur des champs déjà manipulés
    bonjour,
    je voulais simplement savoir pourquoi il n'est pas possible d'effectuer, dans une requète SELECT, une opération sur des champs qui sont déjà le résultat d'autres opérations:

    petit exemple très simple pour illustrer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT
         MAX(nb) AS nb_max,
         MIN(nb) AS nb_min,
         ( nb_max - nb_min ) AS ecart
    FROM tbl_nombres
    cette requète renvoie l'erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Unknown column 'nb_max' in 'field list'
    j'ai seulement MySql 4; faut-il obligatoirement utiliser les fonctions ou procédures ou vues de MySql 5 pour cela?

  2. #2
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    tu ne peux pas,sauf erreur de ma part mettre des alias directement apres le select

    je ferais plus ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT
         MAX(nb) AS nb_max,
         MIN(nb) AS nb_min,
         ( MAX(nb) - MIN(nb) ) AS ecart
    FROM tbl_nombres

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 30
    Points : 22
    Points
    22
    Par défaut
    effectivement, on ne peut pas et c'est justement mon grand désarroi:

    parceque là, j'ai fait un exemple simplissime avec juste MAX et MIN;

    mais dans mon utilisation, les champs nb_max et nb_min sont des résultats de sous-requètes complexes avec des clauses WHERE et tout et tout, donc je ne peux absolument pas répéter les champs complets pour le calcul du champ ecart !

    je dois donc migrer sous MySql 5 et utiliser des VIEW ou PROCEDURE ou FUNCTION ?

  4. #4
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    OK, je comprends mieux ton souci.

    par contre je suis resté a la version 4.1, donc je peux pas trop te dire comment on peut s'en sortir avec les vues

    bon courage

    Michel

  5. #5
    Membre confirmé Avatar de Christophe Charron
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    920
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 920
    Points : 606
    Points
    606
    Par défaut
    Citation Envoyé par Cybher
    salut,

    tu ne peux pas,sauf erreur de ma part mettre des alias directement apres le select

    je ferais plus ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT
         MAX(nb) AS nb_max,
         MIN(nb) AS nb_min,
         ( MAX(nb) - MIN(nb) ) AS ecart
    FROM tbl_nombres
    Cette solution fonctionne au moins depuis la version 4.1...
    Cordialement,
    Christophe Charron

  6. #6
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    oui cela fonctionne mais ce n'est pas ce qu'il cherche...

  7. #7
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Salut,

    Tu peux nous donner la requête qui pose problème ? Il y a peut-être moyen de la simplifier...
    Pensez au bouton

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 30
    Points : 22
    Points
    22
    Par défaut
    en fait, c'était une question d'ordre général, parceque je rencontre ce besoin assez souvent:
    pour l'affichage d'un bilan sous forme de tableau HTML, on a besoin de toutes les colonnes, notamment la colonne total qui est soit une somme, soit une différence, soit un calcul plus complexe avec les colonnes précédentes...

    je fais donc l'opération nécessaire en PhP lorsque je récupère ma requète SQL, mais j'aurais justement aimé la faire directement dans la requète SQL, pour n'utiliser PhP que pour l'affichage HTML.

    j'ai, par exemple pour afficher le bilan des congés pris par les employés sur l'année sélectionnée, une requète du type:
    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
     
    SELECT s.id_salaries, CONCAT(s.prenom,' ',s.nom) as nomcomplet,
     ( SELECT SUM(ad.nb)
       FROM absences_droits as ad
       WHERE ad.id_salarie=s.id_salaries AND ad.annee='$annee' ) as nb_acquis ,
     ( SELECT SUM(IF(type='conges',1,IF(type='demijournee',0.5,0))) 
       FROM absences as a 
       WHERE a.id_salarie=s.id_salaries AND a.type IN ('conges','demijournee') AND a.annee='$annee' AND a.jour <= CURDATE()
       GROUP BY a.id_salarie ) as nb_pris ,
     ( SELECT SUM(IF(type='conges',1,IF(type='demijournee',0.5,0))) 
       FROM absences as a 
       WHERE a.id_salarie=s.id_salaries AND a.type IN ('conges','demijournee') AND a.annee='$annee' AND a.jour > CURDATE()
       GROUP BY a.id_salarie ) as nb_aprendre 
    FROM salaries as s
    ORDER BY nomcomplet
    là, je ne peux bien évidemment pas recopier les champs nb_acquis, nb_pris et nb_aprendre pour faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $nb_prevu = $nb_pris + $nb_aprendre;
    $nb_restant = $nb_acquis - $nb_prevu;
    comme je suis encore sous MySql 4.1, je ne me suis pas encore plongé dans les nouvelles fonctions de MySql 5;
    avez-vous une idée, des conseils?

  9. #9
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    En utilisant des jointures plutôt que des sous-requêtes, les éléments de ton SELECT seraient certainement plus simples et plus facilement utilisables dans des opérations mathématiques.

    Par ailleurs il y a plus de chances que l'optimiseur repère que "SUM(ad.nb)" et "SUM(ad.nb)" sont la même chose, qu'avec "SELECT SUM(ad.nb) FROM absences_droits as ad WHERE blabla..."
    et "SELECT SUM(ad.nb) FROM absences_droits as ad WHERE blabla..."
    Pensez au bouton

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 30
    Points : 22
    Points
    22
    Par défaut
    ha bin justement, çà m'intéresse !! c'est le deuxième gros problème que j'ai en ce moment...

    j'avais justement commencé par des jointures pour éviter que cette requète soit si lourde, mais je n'ai pas trouvé la bonne syntaxe pour obtenir le bon résultat:
    avec une seule jointure de la première table : LEFT JOIN absences_droits, là ça va...
    mais dès que je rajoutais la deuxième jointure LEFT JOIN absences, je n'arrivais pas à choper les bons résultats, puisqu'il me sortait le produit cartésien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT s.id_salaries, CONCAT(s.prenom,' ',s.nom) as nomcomplet,
    SUM(ad.nb) as nb_acquis ,
    SUM(IF(a.type='conges',1,IF(a.type='demijournee',0.5,0))) as nb_prevu
    FROM salaries as s
    LEFT JOIN absences_droits as ad ON s.id_salaries=ad.id_salarie AND ad.annee='$annee'
    LEFT JOIN absences as a ON s.id_salaries=a.id_salarie AND a.type IN ('conges','demijournee') AND a.annee='$annee' 
    GROUP BY s.id_salaries
    ORDER BY nomcomplet
    après plusieurs essais, je n'ai pas obtenu les bons chiffres, j'ai donc abandonné pour me lancer dans les sous-requètes où là, pas de problème de produit cartésien...

    quelle serait la bonne syntaxe de requète de jointure?

  11. #11
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Un truc de ce style peut-être (à l'arrache, pas testé) :

    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
    SELECT s.id_salaries, CONCAT(s.prenom,' ',s.nom) as nomcomplet,
    SUM(ad.nb) as nb_acquis,
    SUM(IF(type='conges',1,IF(type='demijournee',0.5,0))) as nb_pris,
    SUM(IF(type='conges',1,IF(type='demijournee',0.5,0))) as nb_aprendre,
     
    FROM salaries as s 
    LEFT JOIN absences_droits as ad
       ON ad.id_salarie=s.id_salaries 
    LEFT JOIN absences as a
       ON a.id_salarie=s.id_salaries
    LEFT JOIN absences as a2 
       ON a2.id_salarie=s.id_salaries
     
       WHERE ad.annee='$annee'
       AND a.type IN ('conges','demijournee') AND a.annee='$annee' AND a.jour <= CURDATE()
      AND a2.type IN ('conges','demijournee') AND a2.annee='$annee' AND a2.jour > CURDATE()
     
    GROUP BY s.id_salarie
    ORDER BY nomcomplet
    Pensez au bouton

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

Discussions similaires

  1. opération sur des champs
    Par tonia1163 dans le forum IHM
    Réponses: 4
    Dernier message: 22/11/2008, 13h43
  2. Opération sur des heures dans Excel
    Par mirascheat dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 15/12/2005, 10h34
  3. tri sur des champs calculés
    Par Thib dans le forum Bases de données
    Réponses: 10
    Dernier message: 18/10/2005, 17h24
  4. Boucler sur des champs texte
    Par syl2095 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 25/11/2004, 16h15

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