Page 1 sur 2

SELECT avec des conditions

Posté : 29 mars 2006, 14:31
par lord.anonymous
Bonjour à tous. J'ai constitué une petite base de données qui va me servir à gérer l'outillage de plusieurs machines. Je vous explique tout d'abord les données.

Il y a plusieurs machines dans l'atelier, chaque machine a ses outils qui sont montés dedans, et chaque outil possède certaines caractéristiques. Les caractéristiques des outils peuvent changer, et c'est l'utilisateur qui se chargera de le faire.

Pour des raisons de suivi, il est nécessaire de garder en base de donnée tout trace des changements effectués, afin de reconstituer un historique.

Je voudrais construire une requête SQL qui sélectionne, pour une machine donnée, les outils et leurs caractéristiques, mais seulement sur les dernières valeurs entrées.

Voici le code de la base de données: (simple pour le moment)
CREATE TABLE `outils` (
  `id` smallint(6) NOT NULL auto_increment,
  `machine` enum('CH40','CV30','C200','HES300','T20','Tour Hermes') NOT NULL default 'CH40',
  `outil` tinyint(4) NOT NULL default '0',
  `X` float NOT NULL default '0',
  `Z` float NOT NULL default '0',
  `R` float NOT NULL default '0',
  `C` tinyint(4) NOT NULL default '0',
  `edit` varchar(80) NOT NULL default '',
  `date_heure` datetime NOT NULL default '0000-00-00 00:00:00',
  `image` varchar(40) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

INSERT INTO `outils` VALUES (1, 'CH40', 1, 63.156, 130.458, 0, 0, 'Prof2', '2006-03-28 15:35:17', 'Images/CH40.jpg');
INSERT INTO `outils` VALUES (2, 'CH40', 2, 12.85, 36.59, 2, 0, 'Prof2', '2006-03-28 16:32:45', 'Images/CH40.jpg');
INSERT INTO `outils` VALUES (3, 'CH40', 1, 10, 20, 0, 0, 'Eleve', '2006-03-29 09:32:53', 'Images/CH40.jpg');
INSERT INTO `outils` VALUES (4, 'CH40', 2, 12, 22, 2, 0, 'Eleve2', '2006-03-29 12:35:38', 'Images/CH40.jpg');
        
J'ai déjà construit cela, mais ça m'affiche toutes les lignes concernant cette machine...
SELECT `id`, `machine`, `outil`, `X`, `Z`, `R`, `C`, `edit`, `date_heure`, `image` FROM `outils` WHERE `machine`='CH40' ORDER BY `outil`
Je voudrais que la requête ne me prenne en compte pour cette machine, que les dernières valeurs entrées pour l'outil 1 et l'outil 2.

Est ce possible? Comment faire?

Au final, il y aura 6 machines dans la BDD, avec environ 80 outils différents, et plein de modifications sur ces outils.

Posté : 29 mars 2006, 14:43
par Truc
Salut,

Si j'ai bien suivi tu veux récupérer les 2 dernier tuples (lignes de données) pour une machine donnée.

Proposition:
Classeement dans l'ordre décroissant et séléction de 2 tuples
SELECT `id`, `machine`, `outil`, `X`, `Z`, `R`, `C`, `edit`, `date_heure`, `image` FROM `outils` WHERE `machine`='CH40' ORDER BY `id` DESC ,`outil` LIMIT 0 , 2

Posté : 29 mars 2006, 14:49
par lord.anonymous
Salut!
Merci pour ta réponse.
Ceci fonctionne dans le cas où il y a 2 outils, mais c'était un "cas d'école".
J'en ai 40 dans cette machine.
Je veux bien mettre la limite à 40... mais je crois que ça ne change pas le fond de mon problème.

Je réexplique:
- pour une machine donnée, je veux récupérer la dernière valeur enregistrée des caractéristiques d'un outil, sachant que ça s'affichera dans un tableau de la machine, où seront affichés tous les outils avec les valeurs à jour.

Posté : 29 mars 2006, 15:22
par lord.anonymous
Personne n'a un idée? Je sèche là dessus depuis quelques heures.

Posté : 29 mars 2006, 16:02
par lord.anonymous
Help!

Posté : 29 mars 2006, 16:05
par ouckileou
Help!
ça fait une 1h30 que tu as posté ton premier messsage, ce n'est pas la mort, ne sois pas impatient

Il y a des gens qui travaillent aussi :roll:

Posté : 29 mars 2006, 16:07
par lord.anonymous
Help!
ça fait une 1h30 que tu as posté ton premier messsage, ce n'est pas la mort, ne sois pas impatient

Il y a des gens qui travaillent aussi :roll:
Bah tu dois savoir comme moi qu'il est énervant de sécher un certain temps sur une question et de bloquer ainsi tout l'avancement d'un projet...
Je n'en veux à personne de ne pas intervenir, mais je tourne en rond dans ce problème et ça m'obsède.

Posté : 29 mars 2006, 16:20
par ouckileou
Oui je le sais, mais des commentaires qui peuvent être pris pour de l'impatience ne vont pas t'aider à avoir des réponses

Code : Tout sélectionner

SELECT `id`, `machine`, `outil`, `X`, `Z`, `R`, `C`, `edit`, `date_heure`, `image` FROM `outils` WHERE `machine`='CH40' ORDER BY `outil`, date_heure DESC
Te renvoie tes infos triées par outil puis par date

Si tu ne veux n'afficher que le plus récent, tu peux ensuite gérer ça dans le code
Pour le premier outil, et ensuite dès que tu changes, tu affiches la ligne correspondante

Code : Tout sélectionner

outilCourant <- VIDE TantQue il reste des lignes de résultat Faire Si outilCourant est VIDE ou si outilLigne est différent de outilCourant Alors outilCourant <- outilLigne afficher infos FSi FTantQue

Posté : 29 mars 2006, 16:41
par lord.anonymous
Je peux faire comme cela, j'y avais pensé, mais est-ce possible de contruire une requête qui me permettrait de le faire?

Posté : 29 mars 2006, 16:46
par ouckileou
Avec tout stocké dans une même table, non je ne pense pas

Tu aurais séparé Outils et Mises à jour peut-être, et encore je ne sais pas comment, si ce n'est en rajoutant une colonne "date_maj" dans ta table "Outils"
Tu aurais comme ça une table recensant les diverses modifications de config, à chaque insertion tu mettrais à jour "date_maj" dans Outils
ce qui te permettrait de relier dans ta requête de sélection les deux tables sur le numéro d'outil et sur la date

A part ça je ne vois pas trop là

Posté : 29 mars 2006, 17:09
par Truc
Effectivement je n'ai pas répondu à la question... que j'vais mal comprise :wink:

Le traitement par programmation semble inévitable, soit ça soit modification de la structure.

Posté : 29 mars 2006, 17:11
par lord.anonymous
Il n'existe pas une fonction INTERSECTION au lieu de UNION qui pourrait m'aider à faire ce genre de requête?

Posté : 29 mars 2006, 17:20
par lord.anonymous
Je vais partir sur 2 tables séparées: une qui contient les données mises à jour et uniquement elles, et une deuxième table qui contiendra l'historique complet. Cette seconde table ne servira pas à la lecture puisqu'en consultation les seules choses qui nous intéressent ce sont les dernières valeurs à jour. Par contre j'avais besoin d'un historique afin de pouvoir pister les modifications en cas de "phénomène étrange"...

Posté : 29 mars 2006, 17:22
par ouckileou
Il n'existe pas une fonction INTERSECTION au lieu de UNION qui pourrait m'aider à faire ce genre de requête?
Je ne vois pas ce que ça vient faire ici, puisque de toute façon tu n'as qu'une seule table

Mais même avec 2 tables
Union : tu récupèrerais toutes les lignes des 2 tables
Intersection : tu récupèrerais toutes les lignes en commun

Toi il te faudrait une jointure, sur numéro Outil, avec une condition pour ne garder que la date maxi à chaque fois
Et là comme ça je ne vois pas comment faire désolé

Posté : 29 mars 2006, 17:27
par ouckileou
Je vais partir sur 2 tables séparées: une qui contient les données mises à jour et uniquement elles, et une deuxième table qui contiendra l'historique complet. Cette seconde table ne servira pas à la lecture puisqu'en consultation les seules choses qui nous intéressent ce sont les dernières valeurs à jour. Par contre j'avais besoin d'un historique afin de pouvoir pister les modifications en cas de "phénomène étrange"...
A ce moment là pourquoi ne pas mettre en place ma suggestion précédente : une colonne "dernière_maj", en séparant Outils et MàJ

ça revient plus ou moins au même, sauf que tu évites la redondance des données et tu gagnes de la place ;)