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 MySQL Discussion :

Sélection avec SUM ou COUNT ou pas possible ?


Sujet :

Requêtes MySQL

  1. #1
    Futur Membre du Club
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 5
    Points
    5
    Par défaut Sélection avec SUM ou COUNT ou pas possible ?
    Bonjour,

    Ma table Hotel se décrit par Num_Chambre, Carac1, Carac2, Carac3, Carac4, Carac5

    J'aimerais pouvoir mettre une note à chaque chambre. Pour se faire je dois compter le nombre de caractéristique qu'à la chambre en question.
    Pour chaque caractéristique je peux avoir les valeurs X, 1, 2.
    Si la chambre a les caractéristiques :
    • 1 = 1,
    • 2 = X,
    • 3 = 2,
    • 4 = 1,
    • 5 = 1

    j'aimerais comptabiliser les caractéristiques = 1 puis = 2.
    Résultat
    • 3 caractéristiques à 1 et,
    • 1 caractéristique à 2.


    Ainsi je pourrais lui mettre une note, qui sera différente d'une autre chambre ayant toutes les caractéristiques avec une note à 1.

    C'est pourquoi je ne peux pas faire une simple somme des notes de chaque caractéristique parce que je ne pourrais pas différencier la chambre de l'exemple (où la somme aurait fait 5) de la chambre dont toutes les caractéristiques serait à 1 (ce qui fait également 5).

    Auriez vous une idée de comment faire?
    Est-ce possible avec une requête SQL?

    Merci par avance pour votre aide !!

  2. #2
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonjour.

    Comme il s'agit de colonnes différentes, un COUNT ne fonctionnera pas, il fonctionnerait s'il s'agissait d'une même colonne pour des tuples différents.

    En SQL standard je ne vois pas trop de solution par contre c'est faisable assez facilement avec de nombreux langages. Tu pourrais même faire une procédure stockée pour ça à la limite si la syntaxe MySQL te le permet.

    Voici un exemple d'algorithme :

    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
    21
    22
    23
    24
    25
    ajout_array(array_hash, valeur){
        SI valeur est une clef de array_hash ET valeur != 'X' ALORS
            array_hash[valeur]=array_hash[valeur]+1;
        SINON SI valeur != 'X' ALORS
            array_hash[valeur]=1;
        FIN SI
    }
     
    sql="SELECT Num_Chambre, Carac1, Carac2, Carac3, Carac4, Carac5 FROM TABLE";
     
    resultat=execution(sql);
     
    POUR CHAQUE tuple de resultat FAIRE
        array_hash = new array();
        ajout_array(array_hash, tuple.Carac1);
        ajout_array(array_hash, tuple.Carac2);
        ajout_array(array_hash, tuple.Carac3);
        ajout_array(array_hash, tuple.Carac4);
        ajout_array(array_hash, tuple.Carac5);
     
        Afficher "Voici le détail des carractéristiques pour " + tuple.NumChambre + " : ";
        POUR CHAQUE clef de array_hash FAIRE
            Afficher "Pour la valeur " + clef + " : " + array_hash[clef] + " occurrences";
        FIN POUR
    FIN POUR
    Algo à adapter en fonction du besoin. Par exemple tu peux rajouter un paramètre NumChambre en entrée. Tu peux retourner le tableau au lieu de l'afficher (dans ce cas faudra faire un tableau 2D)...

    Toutefois, il aurait été plus intelligent d'avoir un schéma des tables plus relationnel comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Chambre(NumChambre, ...) -0,5-(posséder(note))-0,n-Carractéristiques(NumCarractéristique, ...)
    Et ainsi d'avoir les tables suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Chambre(NumChambre, ...)
    Carractéristiques(NumCarractéristique, ...)
    Posseder(NumChambre#, NumCarractéristique#, note)
    Tu pourrais même le simplifier à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Chambre(NumChambre, ...)
    Posseder(NumChambre#, NumCarractéristique, note)
    Si l'entité "Carractéristique" ne contient rien d'autre qu'un id.

    En toute rigueur ça impliquerait d'avoir un traitement qui vérifie que la relation "Posseder" ne contient pas plus de 5 tuples pour un même NumChambre (ce qui n'est pas sorcier) mais tu tirerait les deux gros avantages suivants :
    - Avec une simple requête d'agrégat, là tu pourrait satisfaire ton besoin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT Note, COUNT(NumCarractéristique)
    FROM Posseder
    WHERE NumChambre = XXX
    GROUP BY Note;
    - Ça t'évites en plus l'horrible bidouille de la valeur "X" que tu utilise actuellement (par exemple si pas de note pour Carac 3 pour la chambre 1, pas d'entrées dans "Posséder" pour NumCarractéristique = 3 et NumChambre = 1).

    Dès lors que tu as des colonnes aux significations identiques, c'est de la redondance et, sauf si une contrainte de perf t'en empêche (parce que tu veux éviter les grosses jointures...), il faut créer une table associative comme dans l'exemple précédant.

    Cordialement,
    Idriss

  3. #3
    Futur Membre du Club
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 5
    Points
    5
    Par défaut
    Merci, c'est bien ce qu'il me semblait, une requête ne suffit pas.
    La solution de plusieurs tables est surement le plus propre et le plus maintenable par la suite.

    Ma table étant déjà rempli je ne peux plus me permettre de revoir la conception. Je vais partir sur la solution de sauvegarde des tuples.

    Merci pour ta réponse. Je laisse ouvert la porte quelques jours pour savoir si d'autres aurait une solution.

  4. #4
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Ma table étant déjà rempli je ne peux plus me permettre de revoir la conception. Je vais partir sur la solution de sauvegarde des tuples.
    Sauvegarder les tuples dans quel sens ?

    Sinon, si ta volumétrie n'est pas trop importante, tu peux faire une moulinette qui remplie tes nouvelles tables à partir des anciennes. Puis supprimer les anciennes et renommer les nouvelles si l'insertion s'est bien passée .

  5. #5
    Futur Membre du Club
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 5
    Points
    5
    Par défaut
    Par sauvegarder des tuples je veux dire : je parcours ma table occurrence par occurrence et pour chaque occurrence je calcul la note. C'est ta première solution.

  6. #6
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Et sinon quelle est la volumétrie actuelle de ta bdd ? (Combien de tuples, quelle taille, etc).

    Si j'ai bien compris, il s'agit des chambres d'un hôtel, donc ça ne devrait pas dépasser le millier de tuples. Vu la taille des colonnes de ton schéma, ça reste une petite volumétrie et ça vaut surement le coup de faire une moulinette afin de remettre tout bien d'équerre

    Faudra le faire en plusieurs étapes :

    1 - Tu créer les nouvelles table avec un suffixe "tmp" (par exemple) pour celle dont le nom est déjà occupé.
    2 - Tu applique ta moulinette afin de les remplir à partir de l'ancienne table.
    3 - Tu vérifie que tout est bien inséré et cohérent (tu peux t'aider d'un script pour ça qui fait une sorte de diff entre ton ancienne table et les nouvelles => pour chaque chambre, ais-je bien les même notes sur l'ancienne table et les nouvelles ?).
    4 - Si tout est OK, tu supprime ton ancienne table et tu renomme la nouvelle table portant le flag "TMP". Si c'est pas OK, l'ancienne table n'aura pas été impactée, et tu ne fera pas de régression ainsi. Si le taux d'erreur est faible, tu pourra aussi le corriger à la main en te calquant sur les valeurs de l'ancienne table mais tu ne devrait pas avoir à en venir là.

    En plus, tu devrait faire un dump juste avant cette manip donc au pire des cas, rebasculer sur ce dump.

    Cordialement,
    Idriss

  7. #7
    Futur Membre du Club
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 5
    Points
    5
    Par défaut
    Non non tu as raison vaut mieux que je fasse ce que tu dis. J'ai une centaine de tuple, même à la main c'est faisable.

    Merci encore pour ton aide.

    A bienôt

  8. #8
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    C'est surement faisable avec une seule requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT num_chambre, nbCar1, nbCar2
    FROM
    (
    	SELECT num_chambre, @nbCar1:=0, @nbCar2:=0,
    		IF(carac1=1,@nbCar1:=@nbCar1+1,IF(carac1=2,@nbCar2:=@nbCar2+1,0)),
    		IF(carac2=1,@nbCar1:=@nbCar1+1,IF(carac2=2,@nbCar2:=@nbCar2+1,0)),
    		IF(carac3=1,@nbCar1:=@nbCar1+1,IF(carac3=2,@nbCar2:=@nbCar2+1,0)),
    		IF(carac4=1,@nbCar1:=@nbCar1+1,IF(carac4=2,@nbCar2:=@nbCar2+1,0)),
    		IF(carac5=1,@nbCar1:=@nbCar1+1,IF(carac5=2,@nbCar2:=@nbCar2+1,0)),
    		@nbCar1 AS nbCar1, @nbCar2 AS nbCar2
     FROM hotel
    ) tmp
    Mais il est vraiment préférable de faire ce qu'Idriss t'a conseillé.

  9. #9
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Ah la syntaxe MySQL le permet , merci pour cette information

    Bon sinon quand je disait "pas faisable en une requête" je parlais d'une requête en SQL standard. Après de toute façon, il est préférable de partir sur une conception propre ce qui simplifiera la requête.

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

Discussions similaires

  1. Requêt avec sum ne donne pas le bon résultat§
    Par _cece dans le forum Langage SQL
    Réponses: 10
    Dernier message: 04/11/2008, 18h53
  2. Select count avec jointure, en récupérant les 0 : possible ?
    Par littlewings dans le forum Requêtes
    Réponses: 2
    Dernier message: 17/07/2008, 12h57
  3. Requete avec sum et count
    Par jcserre dans le forum Langage SQL
    Réponses: 1
    Dernier message: 14/06/2008, 11h01
  4. Sélection de texte à l'intérieur d'une cellule. C'est [PAS] possible.
    Par Blackfox dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 20/08/2007, 14h01
  5. Vraiment pas possible avec SQLLOADER ?
    Par fguigui dans le forum SQL*Loader
    Réponses: 2
    Dernier message: 20/09/2006, 10h43

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