Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Débuter
Débuter Forum d'entraide pour débuter avec MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/05/2007, 11h48   #1
Invité de passage
 
Inscription : mai 2007
Messages : 17
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 17
Points : 2
Points : 2
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
bzhades est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 12h10   #2
Membre Expert
 
Avatar de zoom61
 
Homme Vincent ...
Passionné d'informatique
Inscription : janvier 2005
Messages : 1 217
Détails du profil
Informations personnelles :
Nom : Homme Vincent ...
Âge : 39
Localisation : France, Haute Vienne (Limousin)

Informations professionnelles :
Activité : Passionné d'informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2005
Messages : 1 217
Points : 1 506
Points : 1 506
Envoyer un message via Yahoo à zoom61 Envoyer un message via Skype™ à zoom61
Salut,

Voici le code qui devrait fonctionner :
Code :
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;
__________________
N'oubliez pas le Tag :

C'est en parvenant à nos fins par l'effort, en étant prêt à faire le sacrifice de profits immédiats en faveur du bien-être d'autrui à long terme, que nous parviendrons au bonheur caractérisé par la paix et le contentement authentique. [Dalaï Lama]
Je ne réponds pas aux messages privés s'ils sont liés à une question du forum

Mon site sur Developpez.com
zoom61 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 13h11   #3
Invité de passage
 
Inscription : mai 2007
Messages : 17
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 17
Points : 2
Points : 2
Merci de ta réponse, mais malheureusement, celà ne marche pas

Code :
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)
bzhades est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 13h47   #4
Membre Expert
 
Avatar de zoom61
 
Homme Vincent ...
Passionné d'informatique
Inscription : janvier 2005
Messages : 1 217
Détails du profil
Informations personnelles :
Nom : Homme Vincent ...
Âge : 39
Localisation : France, Haute Vienne (Limousin)

Informations professionnelles :
Activité : Passionné d'informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2005
Messages : 1 217
Points : 1 506
Points : 1 506
Envoyer un message via Yahoo à zoom61 Envoyer un message via Skype™ à zoom61
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 ?
__________________
N'oubliez pas le Tag :

C'est en parvenant à nos fins par l'effort, en étant prêt à faire le sacrifice de profits immédiats en faveur du bien-être d'autrui à long terme, que nous parviendrons au bonheur caractérisé par la paix et le contentement authentique. [Dalaï Lama]
Je ne réponds pas aux messages privés s'ils sont liés à une question du forum

Mon site sur Developpez.com
zoom61 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 13h58   #5
Invité de passage
 
Inscription : mai 2007
Messages : 17
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 17
Points : 2
Points : 2
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
bzhades est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 14h06   #6
Membre Expert
 
Avatar de zoom61
 
Homme Vincent ...
Passionné d'informatique
Inscription : janvier 2005
Messages : 1 217
Détails du profil
Informations personnelles :
Nom : Homme Vincent ...
Âge : 39
Localisation : France, Haute Vienne (Limousin)

Informations professionnelles :
Activité : Passionné d'informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2005
Messages : 1 217
Points : 1 506
Points : 1 506
Envoyer un message via Yahoo à zoom61 Envoyer un message via Skype™ à zoom61
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 :
1
2
3
4
5
6
SELECT ...
FROM ...
WHERE A = (SELECT ... (1 seul champ)
                  FROM ...
                  WHERE ...)
GROUP BY ...
__________________
N'oubliez pas le Tag :

C'est en parvenant à nos fins par l'effort, en étant prêt à faire le sacrifice de profits immédiats en faveur du bien-être d'autrui à long terme, que nous parviendrons au bonheur caractérisé par la paix et le contentement authentique. [Dalaï Lama]
Je ne réponds pas aux messages privés s'ils sont liés à une question du forum

Mon site sur Developpez.com
zoom61 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 14h14   #7
Invité de passage
 
Inscription : mai 2007
Messages : 17
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 17
Points : 2
Points : 2
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
bzhades est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 14h40   #8
Membre Expert
 
Avatar de zoom61
 
Homme Vincent ...
Passionné d'informatique
Inscription : janvier 2005
Messages : 1 217
Détails du profil
Informations personnelles :
Nom : Homme Vincent ...
Âge : 39
Localisation : France, Haute Vienne (Limousin)

Informations professionnelles :
Activité : Passionné d'informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2005
Messages : 1 217
Points : 1 506
Points : 1 506
Envoyer un message via Yahoo à zoom61 Envoyer un message via Skype™ à zoom61
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 :
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.

__________________
N'oubliez pas le Tag :

C'est en parvenant à nos fins par l'effort, en étant prêt à faire le sacrifice de profits immédiats en faveur du bien-être d'autrui à long terme, que nous parviendrons au bonheur caractérisé par la paix et le contentement authentique. [Dalaï Lama]
Je ne réponds pas aux messages privés s'ils sont liés à une question du forum

Mon site sur Developpez.com
zoom61 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 15h58   #9
Invité de passage
 
Inscription : mai 2007
Messages : 17
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 17
Points : 2
Points : 2
ok, je vais essayer tout ca... je te redit ca dès que j'ai réussit à avancer
bzhades est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 16h39   #10
Invité de passage
 
Inscription : mai 2007
Messages : 17
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 17
Points : 2
Points : 2
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 :
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
bzhades est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 16h57   #11
Membre Expert
 
Avatar de Sivrît
 
Inscription : février 2006
Messages : 953
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 953
Points : 1 189
Points : 1 189
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
Sivrît est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 17h23   #12
Membre Expert
 
Avatar de Sivrît
 
Inscription : février 2006
Messages : 953
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 953
Points : 1 189
Points : 1 189
Le plus efficace semble être dans le genre :
Code :
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.
Sivrît est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 17h30   #13
Invité de passage
 
Inscription : mai 2007
Messages : 17
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 17
Points : 2
Points : 2
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 :
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 :
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 ^_^
bzhades est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 18h17   #14
Membre Expert
 
Avatar de Sivrît
 
Inscription : février 2006
Messages : 953
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 953
Points : 1 189
Points : 1 189
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 :
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 :
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).
Sivrît est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2007, 18h19   #15
Invité de passage
 
Inscription : mai 2007
Messages : 17
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 17
Points : 2
Points : 2
effectivement, ca marche mieux avec la virgule qui va bien ^_^

Bah voilà, mon problème est résolé, merci énormément!!!
bzhades est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 03h33.


 
 
 
 
Partenaires

Hébergement Web