Page 1 sur 2
Organisation de ma (mes) tables ??
Posté : 11 mars 2005, 18:11
par vins1892
Bonjour,
j'ai posté ce problème dans la rubrique débuter en php, mais je pense qu'il a aussi sa place dans cette rubrique.
Quelqu'un peut-il jeter un coup d'oeil à la fin du post à
http://www.phpfrance.com/forums/voir_sujet-816.php
et éventuellement m'aider ?
D'avance merci.
Posté : 14 mars 2005, 12:38
par sadeq
Votre message d'origine est :
Bon, j'ai suivi vos conseils. J'ai créé la table tirage_tbl suivante:
dtirage num1 num2 num3 num4 num5 num6 numérocompl
23/2/01 1 2 3 12 14 10 11
22/2/00 7 25 28 30 40 41 38
..... ......
Imaginons que je demande combien de fois mes n° 1,2,3,4,5,6 et le complémentaire le 7 sont sortis:
J'ai regardé la doc sur les fonctions agrégats:
select dtirage count (num1,num2,num3,num4,num5,num6,numérocompl) from tirage_tbl
where (1,2,3,4,5,6) in num1 or (1,2,3,4,5,6) in num2 or (1,2,3,4,5,6) in num3 or (1,2,3,4,5,6) in num4 or (1,2,3,4,5,6) in num5 or (1,2,3,4,5,6) in num6
and numérocompl = 7
and count() > 3
goup by dtirage;
La requête devrait me ramener 3 bons numéros le 23/2/01, mais ce n'est pas du tout le cas
Quelqu'un peut-il m'aider ?
En fait, la structure de la table ne permet pas de compter les numéros de tirages puisqu'il n'y a qu'un enregistrement par tirage dans votre cas.
La solution conceptuelle est de dire que les tirages doivent être stockés dans la table "tirage_tbl" dont la structure est :
tirage_tbl (dtirage, num, numérocompl)
où le champ "dtirage" ne doit pas être une clé primaire puisqu'une date de tirage correspond à plusieurs numéros.
Le contenu de cette table peut être alors :
dtirage, num, numérocompl
23/2/01, 1 , 11
23/2/01, 2 , 11
23/2/01, 3 , 11
23/2/01, 12, 11
23/2/01, 14, 11
23/2/01, 10, 11
22/2/00, ...., 38
....
Ici, on voit bien que les dates se multiplient en 6 numéro de trirage, le n° complémentaire est identique pour les mêmes tirage (option simplifiable)
La requête correcte est :
Code : Tout sélectionner
SELECT dtirage, count (num) as bons_numéros FROM tirage_tbl
WHERE num in (1,2,3,4,5,6)
AND numérocompl = 11
GROUP BY dtirage;
La requête proposée, regroupe la table par date en comptant le nombre de n° qi répondent aux critères dans le WHERE (bons numéros)
Simplification:
Je disais que le même n° complémentaire se multiplie autant de fois comme la date de tirage. Ce qui peut être simplifié par la conception suivante :
un tirage daté a un numéro complémentaire et plusieurs numéros de tirage, on a donc une occurence de tirage qui correspond à un lot de numéros (max 6), d'où les tables suivantes :
- 1. la table tirage : tirage_tbl (dtirage, numérocompl)
2. et la table des numéros : numéros(dtirage, num) où les n° sont stockés par date. dtirage ici est une clé étrangère (index avec doublons)
alors qu'elle est concidérée clé primaires dans la table tirage_tbl.
Contenu possible et requête finale:
TABLE : tirage_tbl
dtirage, numérocompl
23/2/01, 11
22/2/00, 38
....
TABLE : numéros
dtirage, num
23/2/01, 1
23/2/01, 2
23/2/01, 3
23/2/01, 12
23/2/01, 14
23/2/01, 10
22/2/00, ....
....
REQUETE : compte des bons tirages par date
Code : Tout sélectionner
SELECT tirage_tbl.dtirage , count (num) as bons_numéros FROM tirage_tbl, numéros
WHERE tirage_tbl.dtirage = numéros.dtirage
AND num in (1,2,3,4,5,6)
AND numérocompl = 11
GROUP BY tirage_tbl.dtirage ;
L'avantage est l'économie de la taille de la base de données.
Normalement cette requête affiche, pour le jeu d'essai donné en exemple :
dtirage , bons_numéros
23/2/01, 3
...
Les dates qui n'apparaissent pas n'ont aucun bons numéro.
Si tu veux resteindre le résultat aux tirages ayant plus de 3 bons numéros, il faut écrire :
Code : Tout sélectionner
SELECT dtirage, count( num ) AS bon_numéros
FROM `tirage_tbl`
WHERE num
IN ( 1, 2, 3, 4, 5, 6 )
AND numérocompl = 11
GROUP BY dtirage
HAVING count( num ) > 3
Dans ce cas là, le même jeu d'essai de l'exemple ne retourne pas de résultat, puisqu'il n'y a que trois bons numéros pas plus.
Posté : 14 mars 2005, 14:01
par vins1892
Bon et bien tout d'abord un tout grand merci pour ton aide, je vais reformater le fichier en format CSV pour pouvoir mettre la DB au format que tu proposes ....
Je me rends compte qu'un cas pourrait poser problème ...
En effet, 5 bons + le complémentaire ou 6 bons n° seront-ils interprétés ?
En fait, les résultats devront se classer en:
3 bons n°;
4 bons n°;
5 bons n°;
5 bons n° + le complémentaire;
6 bons n°.
Posté : 14 mars 2005, 14:24
par sadeq
Certainement, en modifiant simplement la requête en :
SELECT dtirage, count( num ) AS bons_numéros, (numérocompl LIKE 11) AS AvecComplément
FROM tirage_tbl
WHERE num
IN ( 1, 2, 3, 4, 5, 6 )
GROUP BY dtirage
Retourne por le même exemple :
dtirage, bons_numéros, AvecComplément
23/02/01, 3, 1
Posté : 14 mars 2005, 18:00
par vins1892
J'comprends pas ...
Le complémentaire est le 11 et je fais un select sur 1,2,3,4,5,6: le 11 n'est pas dedans. Le résultat doit être 23/02, 3.
ca devrait pas être quelque chose du style:
SELECT dtirage, count( num ) AS bon_numéros
FROM `tirage_tbl`
WHERE num
IN ( 1, 2, 3, 4, 5, 6 )
OR
num in ( 1, 2, 3, 4, 5, 6 ) AND numérocompl = 11
GROUP BY dtirage
HAVING count( num ) > 3
Désolé pour toutes ces questions ...
Posté : 14 mars 2005, 18:54
par sadeq
Oui, je comprends. Tu veux dire que le complétaire ne doit pas être compris dans le compte et s'il est bon il faut le signalé par le texte "+complémentaire" ?!
Dans ce cas la requête est :
Code : Tout sélectionner
SELECT dtirage,
count( num ) AS bons_numéros,
IF (
numérocompl
LIKE 11 , '+ complémentaire', '') AS AvecComplémentaire
FROM tirage_tbl
WHERE num IN ( 1, 2, 3, 4, 5, 6 )
GROUP BY dtirage
HAVING count( num ) >= 3
Car le count(num) ne compte que les num's valides n°complémentaire non compris.
Maintenant l'affichage est :
dtirage, bons_numéros, AvecComplément
23/02/01, 3, + complémentaire
Puisque dans les données exemple, il y a 3 bons n° + le complémentaire ça fait 4.
Posté : 15 mars 2005, 10:05
par vins1892
J'essaye ce soir et te reviens pour te dire si c'est bon ...
Mon but, c'est d'afficher les résultats suivants:
X fois 3 bons numéros;
X fois 4 bons numéros;
X fois 5 bons numéros;
X fois 5 bons numéros + le complémentaire;
X fois 6 bons numéros.
Soit les combinaisons du lotto belge qui rapporte quelque chose ...
Donc, 3 ou 4 bons n° seulement, pas besoin de connaître si j'avais le compl ou pas ...
Je vais faire 4 requêtes différentes en modifiant chaque fois le having:
HAVING count( num ) >= 4;
HAVING count( num ) = 5;
HAVING count( num ) = 5 and numérocompl LIKE 11;
HAVING count( num ) = 6.
J'essaye et te dis quoi ....
A+,
Posté : 17 mars 2005, 10:07
par vins1892
Bonjour,
j'ai rempli les 2 tables avec les données réelles de l'année 1978 ... J'ai testé les requêtes, mais j'ai un souci avec celles sur les jointures ...
Dans un 1er temps, je vais laisser de côté et faire les requêtes uniquement sur les numéros hors numéros complémentaires (ne nécessite pas de jointure), comme ci-dessous:
select dtirage,count(num) AS bons_numero from tirage_tbl where num in (17,18,19,20,21,22) group by dtirage having count(num)=3;
Ca donne comme résultat:
dtirage bons-numero
1978-02-04 3
1978-04-11 3
1978-09-30 3
Comment puis-je organisser ma requête pour avoir comme résultat:
3 tirages avec 3 bons numeros.
Le but est toujours de formuler correctement la requêt SQL pour la transposer en PHP ensuite ...
Je dois quand même garder la notion de dtirage puisque je souhaite ensuite faire un lien vers une autre table se présentant comme suit:
dtirage gain 3 bons n° gain 4 bons n°
1978-02-04 5 EUR 12 EUR
1978-04-11 10 EUR 20 EUR
1978-09-30 4 EUR 30 EUR
1978-12-29 15 EUR 40 EUR
3 tirages avec 3 bons numeros vous auraient rapporté 19 EUR.
D'avance je vous remercie pour vos éclaircissements ....
A+
Posté : 17 mars 2005, 15:34
par sadeq
PRIMO: Pour compter les 3 bons tirages s'ils existent, la requête est la suivante:
On compte le nombre de dates pour un même nombre de bons_numeros.
SELECT count( temp.* ) AS tirages, temp.bons_numeros
FROM (
SELECT dtirage, count( num ) AS bons_numeros
FROM tirage_tbl
WHERE num
IN ( 1, 2, 3, 4, 5, 6 )
GROUP BY dtirage
HAVING count( num ) =3
) AS temp
GROUP BY temp.bons_numeros
La requête contient une sous-requête imbriquée appellée "temp", puisque
temp doit d'abord trouver les dates des bons tirages et notre requête principale compte le nombre de dates trouvées par temp.
SECONDO: Il n'est pas logique d'intégrer le champ dtirage dans la requête principale puisque le compte concerne plusieurs dates.
Toutefois, tu peux toujours te servir de la requête "temp" séparémment pour le détail des dates.
Posté : 30 mars 2005, 13:25
par vins1892
Bonjour, je viens de tester et sql retourne une erreur de syntaxe. Par contre, la 2ème partie de la requête fonctionne:
select dtirage,count(num) AS bons_numeros from tirage_tbl where num in(17,18,19,20,21,22,23) group by dtirage having count(num)=3;
donne comme résultat:
dtirage bons_numeros
1978-02-11 2
1978-02-18 2
1978-03-11 2
Quelqu'un a-t-il une idée de l'erreur ?
Je teste la requête sur phpmyadmin 2.2.6 et la version de mysql est 3.23.49: possible que le problème vienne de là ?
Posté : 30 mars 2005, 14:40
par sadeq
Le support des commandes UNION et des sous-requêtes est disponible depuis MySQL 4.0 et 4.1
Posté : 30 mars 2005, 17:28
par vins1892
Ces sous-requêtes sont supportées par php ?
Je m'explique: si je nomme ma requête sql en $sql et que j'utilise cette variable dans mon code php, elle sera interpétée correctement ?
Si oui, je vais télécharger la dernière version de mysql ...
Posté : 30 mars 2005, 20:32
par Crulaz
Ces sous-requêtes sont supportées par php ?
On s'en fout de la version du php. C'est celle du mysql qui compte.
Posté : 31 mars 2005, 08:55
par vins1892
Ok, mais ma question était plutôt: cela vaut-il la peine de faire une requête sql avec une sous-requête sans être certain certain que celle-ci sera interprétable en php en utilisant cette requête simplement comme variable ?
Posté : 31 mars 2005, 10:41
par sadeq
Dans la requête :
$sql ="
SELECT count( temp.* ) AS tirages, temp.bons_numeros
FROM (
SELECT dtirage, count( num ) AS bons_numeros
FROM tirage_tbl
WHERE num
IN ( 1, 2, 3, 4, 5, 6 )
GROUP BY dtirage
HAVING count( num ) =3
) AS temp
GROUP BY temp.bons_numeros
";
Ce qui est important pour PHP c'est les champs dans le premier SELECT.
PHP récupère normalement ces champs et les traite.
PHP ne se soucit pas du type de la requête c'est mysql qui l'exécute et renvoi le résultat à PHP.