Bonjour !!
Je débarque assez fraichement dans le monde des requêtes SQL...
Ca fait un bail que je sais faire des requètes de bases, qui ne posent de problème à personne, mais dès qu'on commence à vouloir faire des trucs fun, c'est une autre paire de manches.
J'aimerai simplement que vous m'indiquiez si ma démarche est correcte, et comment je pourrai éventuellement améliorer ma requête .
Pour la petite histoire (zappez si vous êtes pressés) : je développe un jeu php (encore un !..) open source (ça c'est moins fréquent) avec Symfony (ça c'est beaucoup plus rare...).
Je simplifie le problème pour garder l'essentiel (->j'enlève les FK etc...) :
J'ai une table buildings (des bâtiments), qui sont caractérisés par une id, un type et un niveau. Le type est un entier, ça correspond par exemple à une ferme, une caserne, une mine... Le niveau représente la taille de ce bâtiment.
Il est possible d'avoir plusieurs bâtiments du même type.
Un bâtiment ne peut être construit que si certains bâtiments ont été construits et ont atteint un certain niveau. C'est le principe d'un arbre des technologies (-> un graphe valué orienté non cyclique).
Par exemple, une caserne ne peut être construite que si l'on a un marché de niveau supérieur ou égal à 2 et une forge de niveau supérieur ou égal à 3.
Ces relations ne sont pas stockées en BD, mais dans des fichiers de config externes.
Le but de ma requête est de savoir si je peux construire un nouveau bâtiment. Je fournis donc mes conditions à la requête, et elle doit me renvoyer 1 si les conditions sont remplies, et 0 sinon.
Voici la table pour l'exemple :
Et voici une requête avec comme conditions : je veux savoir si j'ai
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 DROP TABLE IF EXISTS `testBuilding`; CREATE TABLE `testBuilding` ( `id` int(11) NOT NULL auto_increment, `type` int(11) NOT NULL, `level` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ; INSERT INTO `testBuilding` (`id`, `type`, `level`) VALUES (1, 0, 2), (2, 0, 3), (3, 1, 4), (4, 2, 5), (5, 1, 3), (6, 0, 2);
au moins un bâtiment de type 0 dont le niveau est supérieur ou égal à 2
ET
au moins un bâtiment de type 1 dont le niveau est supérieur ou égal à 3.
Donc pour résumer, je ne veux pas récupérer ces enregistrements, juste savoir si je les ai bien.
Voici la requête que j'ai créé :
En fait, je récupère, pour les types qui m'intéressent, les rangées ayant le niveau le plus élevé (je m'assure ainsi de l'unicité des types). Je compte ensuite combien j'en ai qui vérifient mes conditions, et je vérifie que ce total vaut bien le nombre de conditions.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 SELECT 1 FROM( SELECT COUNT(type) AS total FROM ( SELECT type, MAX(level) as levelMax FROM `testBuilding` WHERE type=0 or type=1 Group by type) AS temp WHERE (type=0 and levelMax>=2) or (type=1 and levelMax>=3)) AS temp2 WHERE total=2
J'ai l'impression que je me suis pris le choux pour pas grand chose, et qu'il y a moyen de faire beaucoup plus simple. Mais je ne sais pas trop comment...
J'espère que vous pourrez m'aider .
Bonne journée !!
@++
Piwaï
Partager