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

 MySQL Discussion :

Requete MySQL qui ne fonctionne pas


Sujet :

MySQL

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 18
    Points : 9
    Points
    9
    Par défaut Requete MySQL qui ne fonctionne pas
    Bonjour à tous et à toutes

    Je suis sur un projet de base de données qui enregistre l'état des machines (switchs, serveur et autre) dans une base de données MySQL

    Pour cette requete, j'ai donc deux tables,
    - la table T_Materiels qui enregistre les données de chaque materiel (nom, ip, mac, date d'achat etc. et surtout "en_service" qui précise si le materiel est en service ou en stock de secours)
    - La table T_Etats qui va stocker l'état du matériel en fonction du temps (remplie par un script) avec id_materiel (à quel materiel correspond l'état enregistré) et "etat" (oui/non)

    Comme un bon dessin vaut mieux qu'un long discours


    Je veux donc afficher le dernier etat de tous les switch dont en_service est TRUE

    Malheureusement, je sens bien qu'il me manque un truc pour que ca marche. (N'ayant d'autre formation que les tutos internet, c'est pas facile )

    voilà la requete à laquelle j'ai aboutie, qui évidemment ne marche pas

    SELECT T_Materiels.ip, T_Materiels.mac, T_Materiels.nom, T_Materiels.commentaires, T_Materiels.en_service, T_Etats.heure, Last(T_Etats.etat) AS Dernier_etat
    FROM T_Materiels INNER JOIN T_Etats ON T_Materiels.id = T_Etats.id_materiels
    GROUP BY T_Materiels.ip
    HAVING T_Materiels.en_service="TRUE";


    Si une âme charitable pouvait me dépanner, ca m'arrangerait pas mal

    Merci d'avance

  2. #2
    Rédacteur

    Avatar de zoom61
    Homme Profil pro
    ...
    Inscrit en
    Janvier 2005
    Messages
    9 429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : ...
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 9 429
    Points : 58 222
    Points
    58 222
    Billets dans le blog
    11
    Par défaut
    Salut,

    Voici le code qui devrait fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT T_Materiels.ip, T_Materiels.mac, T_Materiels.nom, T_Materiels.commentaires, T_Materiels.en_service, T_Etats.heure, Last(T_Etats.etat) AS Dernier_etat
    FROM T_Materiels INNER JOIN T_Etats ON T_Materiels.id = T_Etats.id_materiels
    WHERE T_Materiels.en_service='TRUE'
    GROUP BY T_Materiels.ip;

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Merci de ta réponse, mais malheureusement, celà ne marche pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Erreur
     
    requête SQL: Documentation
     
    SELECT T_Materiels.ip, T_Materiels.mac, T_Materiels.nom, T_Materiels.commentaires, T_Materiels.en_service, T_Etats.heure, Last(T_Etats.etat) AS Dernier_etat
    FROM T_Materiels
    INNER JOIN T_Etats ON T_Materiels.id = T_Etats.id_materiels
    WHERE T_Materiels.en_service = 'TRUE'
    GROUP BY T_Materiels.ip
    LIMIT 0 , 30
     
    MySQL a répondu:Documentation
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '( T_Etats . etat ) AS Dernier_etat  FROM T_Materiels INNER JOIN T_Etats ON T_Mat' at line 1

    sous access, la même requete me fait un message d'erreur "Vous avez essayé d'exécuter une requête ne comprenant pas l'expression spécifiée "mac" comme une partie de la fonction d'aggrégat."

    si ca peut eclairer du monde (en attendant que je sorte des ténêbres de mon ignorance)

  4. #4
    Rédacteur

    Avatar de zoom61
    Homme Profil pro
    ...
    Inscrit en
    Janvier 2005
    Messages
    9 429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : ...
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 9 429
    Points : 58 222
    Points
    58 222
    Billets dans le blog
    11
    Par défaut
    Salut,

    Pour info : le SQL d'Access et de MySQL ne sont pas identiques.

    Mais ton problème vient de ta commande :
    Last(T_Etats.etat) AS Dernier_etat

    Que veux-tu faire avec ?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Je me suis peut être (surement) mal exprimé ^_^

    Dans la Table T_Materiels, j'ai la liste de mon materiel (en service ou en attente/service après vente)
    pour chaque entrée dans la table materiels dont le en_service est vrai (qui est donc sur le réseau) je veux récupérer le dernier enregistrement dans la table T_Etats (qui est l'historique de fonctionnement des materiels) pour voir si la dernière fois que l'on a été voir (requete ping à la con par exemple) le matériel repondait.

    et au passage, afficher l'heure de vérification d'activité (T_Etats.heure) et diverses informations sur les switchs.

    C'est plus clairs là?

    sachant que j'ai fait 2/3 modification pour être conforme aux règles ^_^ (genre les doublons de colonnes "id" ) mais rien de bien méchant

  6. #6
    Rédacteur

    Avatar de zoom61
    Homme Profil pro
    ...
    Inscrit en
    Janvier 2005
    Messages
    9 429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : ...
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 9 429
    Points : 58 222
    Points
    58 222
    Billets dans le blog
    11
    Par défaut
    Salut,

    Dans ce cas, il faut que tu fasses une sous-requête pour récupérer la dernière valeur et ensuite récupérer toutes les info que tu souhaites sur cet enregistrement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT ...
    FROM ...
    WHERE A = (SELECT ... (1 seul champ)
                      FROM ...
                      WHERE ...)
    GROUP BY ...

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    erf, j'ai jamais appris ca... tu aurais un lien vers un tutorial qui parle de ce point? (ou si tu pouvais me guider un peu, car je vois pas trop comment faire ^_^ -> je suis débutant en SQL )

    Merci en tout cas

  8. #8
    Rédacteur

    Avatar de zoom61
    Homme Profil pro
    ...
    Inscrit en
    Janvier 2005
    Messages
    9 429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : ...
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 9 429
    Points : 58 222
    Points
    58 222
    Billets dans le blog
    11
    Par défaut
    Salut,

    Le but d'une sous-requête et de mettre une requête dans la condition WHERE de ta première requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT ...
    FROM ...
    WHERE A = (SELECT ... (1 seul champ)
                      FROM ...
                      WHERE ...)
    GROUP BY ...
    Le premier SELECT te donne toutes tes informations que tu veux et le second permet de restreindre les données aux valeurs que tu veux.


  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    ok, je vais essayer tout ca... je te redit ca dès que j'ai réussit à avancer

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Bon, j'ai repris ça à tête reposée, et je pense avoir enfin trouvé ma requête, qui n'était pas si complexe que ça, il suffisait juste de penser dans le bon ordre soit, regrouper selon le bon critère.

    Il me reste un problème, celui de récupérer le bon champ t_etats.heure, en effet, lors du GROUP BY, il me met la première heure qu'il trouve, meme avec un ORDER BY ensuite


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT t_materiels.ip, t_materiels.mac, t_materiels.nom, t_materiels.commentaires, t_etats.etat, t_etats.heure
    FROM t_materiels INNER JOIN t_etats ON t_materiels.id_materiels=t_etats.idmateriels
    WHERE t_materiels.en_service="TRUE"
    GROUP BY t_etats.idmateriels
    ORDER BY heure DESC
    ca avance, mais il me reste ce problème, si quelqu'un a encore une idée ici

  11. #11
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Ouaip... sauf que les résultats sont faux

    Pour un groupement basé sur 'idmateriels' il y a plusieurs valeurs de 't_etats.etat' et 't_etats.heure', et aucune garantie sur les valeurs qui vont sortir si ce n'est qu'elles seront issues de l'un des enregistrement tiré du groupement. Vive le loto relationnel

    Un 'SELECT' avec un 'GROUP BY' ne doit sortir que des champs placés dans le 'GROUP BY' ou des fonctions d'aggrégation (MAX, MIN, COUNT, ...). MySQL autorise (mais c'est une fausse gentillesse) quand même les champs hors 'GROUP BY' parce que c'est pratique, mais pour que ce soit correcte il faut généralement que leur valeur soit constante pour un groupe (par exemple parce que l'on groupe sur leur clef primaire). C'est à dire que les ajouter au 'GROUP BY' ne devrait pas modifier le résultat.

    Ici c'est comme le dit zoom61, il faut passer par une sous requête si la version de mysql le permet, ou à défaut une autojointure mais c'est beuark inside

  12. #12
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Le plus efficace semble être dans le genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT t_materiels.ip, t_materiels.mac, t_materiels.nom,
           t_materiels.commentaires,
           (SELECT t_etats.etat
            FROM t_etats 
            WHERE t_materiels.id_materiels=t_etats.idmateriels
            ORDER BY t_etats.heure DESC LIMIT 1) AS etat_matos
    FROM t_materiels
    WHERE t_materiels.en_service="TRUE"
    avec un mysql récent et à condition de se satisfaire de l'état sans heure. Sinon il faut jouer avec CONCAT ou faire intervenir t_etats deux fois.

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Effectivement, ca à l'air de bien marcher, merci beaucoup.

    sinon (si je peux me permettre d'abuser) comment dans ce cas, tu peux récupérer l'heure de dernier etat?, car si j'essaye ces deux codes, ca me met des erreurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT t_materiels.ip, t_materiels.mac, t_materiels.nom,
           t_materiels.commentaires,
           (SELECT t_etats.etat
            FROM t_etats 
            WHERE t_materiels.id_materiels=t_etats.idmateriels
            ORDER BY t_etats.heure DESC LIMIT 1) AS etat_matos
    (SELECT t_etats.heure
            FROM t_etats 
            WHERE t_materiels.id_materiels=t_etats.idmateriels
            ORDER BY t_etats.heure DESC LIMIT 1) AS heure_etat
    FROM t_materiels
    WHERE t_materiels.en_service="TRUE"
    ou encore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT t_materiels.ip, t_materiels.mac, t_materiels.nom, t_materiels.commentaires, (
     
    SELECT t_etats.etat, t_etats.heure
    FROM t_etats
    WHERE t_materiels.id_materiels = t_etats.idmateriels
    ORDER BY t_etats.heure DESC
    LIMIT 1
    ) AS etat_matos
    FROM t_materiels
    WHERE t_materiels.en_service = "TRUE"
    au pire, je peux sans doute m'en passer, mais ca pourrait m'être utile ^_^

  14. #14
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    La première semble pas mal mais il manque une virgule entre les deux sous-requêtes.

    La deuxième me plairait bien (ça serait efficace) mais dans ce contexte la sous requête doit renvoyer une unique valeur. Même si c'est moins pratique on peut tricher avec "CONCAT(t_etats.etat, ' ',t_etats.heure)".

    Sinon le classique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT t_materiels.ip, t_materiels.mac, t_materiels.nom,
           t_materiels.commentaires, t_etats.etat, t_etats.heure
    FROM t_materiels JOIN t_etats USING (id_materiels)
    WHERE t_etats.heure=(SELECT MAX(heure)
                         FROM t_etats
                         WHERE t_materiels.id_materiels=t_etats.idmateriels)

    Tant que l'on reste sur un nombre d'enregistrements restreint tout ça va être kif-kif donc chacun suivant ses goùts... mais index sur t_etats.idmateriels indispensable !



    Edit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT t_materiels.ip, t_materiels.mac, t_materiels.nom,
           t_materiels.commentaires, t_etats.etat, t_etats.heure
    FROM t_materiels
    JOIN (SELECT t_etats.idmateriels AS idmat, MAX(t_etats.heure) AS heureM
          FROM t_etats GROUP BY t_etats.idmateriels
         ) tmp ON tmp.idmat=t_materiels.id_materiels
    JOIN t_etats ON t_etats.idmateriels=tmp.idmat
                 AND t_etats.heure=tmp.heureM;
    Ca me semble bien plus rapide (je chipotte peut-être).

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    effectivement, ca marche mieux avec la virgule qui va bien ^_^

    Bah voilà, mon problème est résolé, merci énormément!!!

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

Discussions similaires

  1. Fonction mysql qui ne fonctionne pas pour un ancien postgreIste
    Par floreasy dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 15/01/2008, 18h49
  2. [Access] requete sql qui ne fonctionne pas
    Par pobrouwers dans le forum Langage SQL
    Réponses: 4
    Dernier message: 15/03/2007, 12h33
  3. requete sql qui ne fonctionne pas
    Par pobrouwers dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 15/03/2007, 09h37
  4. Requete UPDATE qui ne fonctionne pas
    Par JiB@ dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 02/03/2007, 18h06
  5. Requete paramétrée qui ne fonctionne pas
    Par bestall666 dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 18/02/2007, 21h58

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