Vous n'êtes pas identifié(e).
Fév 2012, 10:47
J'ai 4 tables:
etudiants: liste des etudiants
jours: nom des jours
classes: nom des classes
joinTables: table de jointure
Je voudrais lister les etudiants qui ont passe l'examen suivant une date (jours), par classe et par annee (une seule annee presente), je cherche un resultat comme suite:
1ere classe:
Jour1: etudiant1, etudiant2
Jour1: etudiant3, etudiant4
Jour1: etudiant1, etudiant5, etudiant6 // le premier etudiant n a pas termine, donc on continue avec lui
2eme classe:
Jour1: etudiant10, etudiant11
Jour1: etudiant12, etudiant14
Jour1: etudiant10, etudiant11, etudiant12 // les etudiants n ont pas termine
ma requete est:
Le resultat pour la 1ere classe est bon, alors qu'il me donne le meme resultat pour la 2eme classe
voici mes tables
etudiant1,
etudiant2,
etudiant3,
etudiant4
..
..
etudiant N
=============
CREATE TABLE jours
idj
jour
id_c
annee
jour1, 1, 2011
jour2, 1, 2011
jour3, 1, 2011
jour4, 1, 2011
jour5, 1, 2011
jour6, 1, 2011
CREATE TABLE classes
idc
classe
classe1, classe2
CREATE TABLE joinTables
idjoin
idetudiant
idjour
idclasse
annee
* Cas de la 1ere classe
1er jour: 2 etudiants (1 et 2) ont passe l examen dans la 1ere classe
NULL, 1, 1, 1, 2011
NULL, 2, 1, 1, 2011
2eme jour: 2 etudiants (3 et 4) ont passe l examen dans la 1ere classe
NULL, 3, 2, 2, 2011
NULL, 4, 2, 2011
3eme jour: 3 etudiants (1, 5 et 6) ont passe l examen dans la 1ere classe
NULL, 1, 3, 1, 2011
NULL, 5, 3, 1, 2011
NULL, 6, 3, 1, 2011
==============
* Cas de la 2eme classe
1er jour: 2 etudiants (10 et11) ont passe l examen dans la 2eme classe
NULL, 10, 1, 1, 2011
NULL, 11, 1, 1, 2011
2eme jour: 2 etudiants (12 et 14) ont passe l examen dans la 2eme classe
NULL, 12, 2, 1, 2011
NULL, 14, 2, 1, 2011
3eme jour: 3 etudiants (10, 11, 12) ont passe l examen dans la 2eme classe
NULL, 10, 3, 1, 2011
NULL, 11, 3, 1, 2011
NULL, 12, 3, 1, 2011
merci
Hors ligne
y pas d'quoi
a++
Hors ligne
Bonjour,
Au delà de l'état de la modélisation et de la requête sur lesquelles je ne vais faire aucun commentaire, dans votre exemple de saisie, il serait mieux je pense de mettre idc=2 au lieu de 1 pour la 2e classe.
Cordialement,
Jc
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
la modélisation et de la requête sur lesquelles je ne vais faire aucun commentaire
Ben moi, je ne vais pas me gêner pour mettre tout cela au standard SQL 92 (20 ans, serait temps de s'y mettre), et militer, une fois encore, contre le redémarrage de la guerre des étoiles
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne
@Mk: Ben pour te livrer le fond de ma pensée, je savais que la tentation allait être forte pour toi, et je me suis dit, "je vais lui en laisser un peu" :D
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
je recois les etudiants mixtes, ca veut dire, pour le premier jour, les etudiants de la premiere classe et les etudiants de la 2eme classe sont presents dans les 2 classes
1er jour: 2 etudiants (1 et 2) ont passe l examen dans la 1ere classe
1er jour: 2 etudiants (10 et11) ont passe l examen dans la 2eme classe
je recois comme resultat:
1ere classe:
1er jour: les etudiants 1, 2, 10 et 11
2eme classe:
1er jour: les etudiants 1, 2, 10 et 11
Dernière modification par rimie (07-02-2012 01:21:47)
Hors ligne
j'ai rectifie la table jours en mettant nom du jour en chiffre pour que la condition soit valable (joinTables.idjour = jours.jour), voila le code entier:
code PHP:
$type = 2011;
$cat = 'classe1';
$sql = 'SELECT * FROM jours WHERE annee = "'.$type.'" AND id_c = (SELECT idc FROM classes WHERE classe = "'.$cat.'") GROUP BY jour ORDER BY idj ASC';
//echo $sql;
$req = $connexion->query($sql);
$result = $req->fetchAll();
if(empty($result))
{
echo 'Aucune resultat';
}
else
{
echo '<table width="500" border="1">';
echo '<tr>';
echo '<td>Jour</td>';
echo '<td>Etudiants</td>';
echo '</tr>';
foreach($result as $k=>$v)
{
$jour = $v['jour'];
echo '<tr>';
echo '<td>'.$jour.'</td>';
echo '<td>';
//Lister les etudiants
// je mets * temporairement
$sqls = 'SELECT *
FROM joinTables
INNER JOIN etudiants ON joinTables.idetudiant = etudiants.ide
INNER JOIN jours ON joinTables.idjour = jours.jour
AND joinTables.idclasse = jours.id_c
AND joinTables.annee = jours.annee';
//echo $sql;
$reqs = $connexion->query($sqls);
$results = $reqs->fetchAll();
if(empty($results))
{
echo 'Aucun etudiant n a passe l exam';
}
else
{
foreach($results as $kk=>$vv)
{
$nom = $vv['nom'];
echo $etudiant;
}
}
echo '</td>';
echo '</tr>';
}
echo '</table>';
}
?>
Les tables:
--
-- Table structure for table `classes`
--
CREATE TABLE IF NOT EXISTS `classes` (
`idc` INT(2) NOT NULL AUTO_INCREMENT,
`classe` VARCHAR(20) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`idc`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;
--
-- Dumping data for table `classes`
--
INSERT INTO `classes` (`idc`, `classe`) VALUES
(1, 'classe1'),
(2, 'classe2');
-- --------------------------------------------------------
--
-- Table structure for table `etudiants`
--
CREATE TABLE IF NOT EXISTS `etudiants` (
`ide` INT(2) NOT NULL AUTO_INCREMENT,
`nom` VARCHAR(30) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`ide`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=16 ;
--
-- Dumping data for table `etudiants`
--
INSERT INTO `etudiants` (`ide`, `nom`) VALUES
(1, 'etudiant1'),
(2, 'etudiant2'),
(3, 'etudiant3'),
(4, 'etudiant4'),
(5, 'etudiant5'),
(6, 'etudiant6'),
(7, 'etudiant7'),
(8, 'etudiant8'),
(9, 'etudiant9'),
(10, 'etudiant10'),
(11, 'etudiant11'),
(12, 'etudiant12'),
(13, 'etudiant13'),
(14, 'etudiant14'),
(15, 'etudiant15');
-- --------------------------------------------------------
--
-- Table structure for table `jointables`
--
CREATE TABLE IF NOT EXISTS `jointables` (
`idjoin` INT(11) NOT NULL AUTO_INCREMENT,
`idetudiant` INT(11) NOT NULL,
`idjour` INT(11) NOT NULL,
`idclasse` INT(11) NOT NULL,
`annee` VARCHAR(4) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`idjoin`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=15 ;
--
-- Dumping data for table `jointables`
--
INSERT INTO `jointables` (`idjoin`, `idetudiant`, `idjour`, `idclasse`, `annee`) VALUES
(1, 1, 1, 1, '2011'),
(2, 2, 1, 1, '2011'),
(3, 3, 2, 1, '2011'),
(4, 4, 2, 1, '2011'),
(5, 1, 3, 1, '2011'),
(6, 5, 3, 1, '2011'),
(7, 6, 3, 1, '2011'),
(8, 10, 1, 2, '2011'),
(9, 11, 1, 2, '2011'),
(10, 12, 2, 2, '2011'),
(11, 14, 2, 2, '2011'),
(12, 10, 3, 2, '2011'),
(13, 11, 3, 2, '2011'),
(14, 12, 3, 2, '2011');
-- --------------------------------------------------------
--
-- Table structure for table `jours`
--
CREATE TABLE IF NOT EXISTS `jours` (
`idj` INT(3) NOT NULL AUTO_INCREMENT,
`jour` VARCHAR(20) COLLATE utf8_unicode_ci NOT NULL,
`id_c` INT(2) NOT NULL,
`annee` VARCHAR(4) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`idj`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=8 ;
--
-- Dumping data for table `jours`
--
INSERT INTO `jours` (`idj`, `jour`, `id_c`, `annee`) VALUES
(1, '1', 1, '2011'),
(2, '2', 1, '2011'),
(3, '3', 1, '2011'),
(4, '4', 1, '2011'),
(5, '5', 1, '2011'),
(6, '1', 2, '2011'),
(7, '2', 2, '2011');
resultat: etudiant1etudiant2etudiant3etudiant4etudiant1etudiant5etudiant6etudiant10etudiant11etudiant12etudiant14
Dernière modification par rimie (07-02-2012 03:23:17)
Hors ligne
Oui mais tu n'as pas tenu compte de ça, pourquoi cette procrastination ?
Je ne comprends pas ce que tu fais.
Pourquoi cette première requête extérieure à la boucle for puisque tu es en jointure sur la table jours dans la requête interne à la boucle ?
D'autre part, si j'ai bien compris ton message initial d'une rare confusion, tu veux obtenir une rupture sur la classe et, pour chaque classe, sur le jour.
Pour ce faire il faudrait ordonner le résultat dans la requête avec une clause ORDER BY jours.id_c, jours.annee, jours.jour.
Mais ce code est vraiment mal foutu.
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne
- J'ai mis (*) temporairement afin de finaliser les champs a selectionner
- Voila un 2eme essai:
$type = 2011;
$cat = 'classe1';
$sqls = 'SELECT *
FROM joinTables
INNER JOIN etudiants ON joinTables.idetudiant = etudiants.ide
INNER JOIN jours ON joinTables.idjour = jours.jour
AND joinTables.idclasse = jours.id_c
AND joinTables.annee = jours.annee
GROUP BY jour ORDER BY idj ASC
';
//echo $sqls;
$reqs = $connexion->query($sqls);
$results = $reqs->fetchAll();
if(empty($results))
{
echo 'Aucun etudiant n a passe l exam';
}
else
{
echo '<table width="500" border="1">';
echo '<tr>';
echo '<td>Jour</td>';
echo '<td>Etudiants</td>';
echo '</tr>';
foreach($results as $kk=>$vv)
{
$nom = $vv['nom'];
$jour = $vv['jour'];
$idjour = $vv['idjour'];
echo '<tr>';
echo '<td>'.$jour.'</td>';
echo '<td>'.$nom.'</td>';
echo '</tr>';
}
echo '</table>';
}
il me donne juste 3 jours, ainsi que le nom du premier etudiant, les restes etudiants ne sont pas affiches
1: etudiant1
2: etudiant3
3: etudiant1
Dernière modification par rimie (07-02-2012 07:37:02)
Hors ligne
Qui t'a parlé de passer par UN GROUP BY ?
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne
sans le GROUP BY voila:
[img align=C]http://imageshack.us/photo/my-images/401/resultatd.png/[/img]
et pour cette requete voila le resultat:
il me reste qu'a mettre le resultat en bon format
[img align=C]http://imageshack.us/photo/my-images/821/resultat2.png/[/img]
Dernière modification par rimie (07-02-2012 12:51:07)
Hors ligne
comment mettre mon resultat au bon format?
Hors ligne
comment mettre mon résultat au bon format?
Qu'appelles-tu format et surtout bon ?
Comme tu as un peu de chance, je vais t'orienter vers la fonction GROUP_CONCAT de MySQL, à coupler CETTE FOIS-CI avec un GROUP BY jours.id_c, jours.annee, jours.jour.
Au demeurant pourquoi une sous-requête
plutôt qu'une jointure ?
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne
je veux dire par un bon format:
nom jour: liste des etudiants
et ne pas:
jour1: etudiant1
jour1: etudiant2
ainsi de suite
Hors ligne
ca donne:
jour1: etudiant2
jour2: etudiant4
jour3: etudiant6
Hors ligne
Sauf que, si tu réfléchissais avant d'agir, tu aurais compris que ce que tu souhaites concaténer dans le regroupement ce n'est pas le jour qui, GROUP BY oblige, sera forcément unique par groupe, mais les étudiants.
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne
deja teste avec: GROUP_CONCAT(joinTables.idetudiant) et GROUP BY joinTables.idetudiant mais ca donne le meme resultat:
jour1: etudiant1
jour1: etudiant2
...
etc
et avec GROUP_CONCAT(joinTables.idetudiant) SEULS, ca donne:
jour1: etudiant1
et avec GROUP BY jours.jour
jour1: etudiant2
jour2: etudiant4
jour3: etudiant6
Hors ligne
Quand ais-je écrit de faire GROUP BY joinTables.idetudiant ?
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne
j'ai teste par plusieurs propositions, que dois je mettre dans GROUP_CONCAT et GROUP BY
Hors ligne
C'est pourtant évident:
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne
voila:
resultat comme celui que j'ai recu auparavant:
jour1: 1
jour2: 3
jour3: 1
Hors ligne
Plus j'y pense, plus je me dis qu'on aurait dû, beaucoup plus en amont de ce post, discuter de la pertinence de la modélisation.
Par exemple, si la table jointures est une liaison à trois pattes entre les tables etudiants, jours et classes peux-tu expliquer la présence de la clé étrangère id_c (qui représente la clé de la table classes) également au sein de la table jours.
Dans cette même table jointures à quoi sert la colonne idjoin, puisque sa clé devrait être une composition des trois autres clés étrangères {`idetudiant`, `idjour`, `idclasse`}. De même que la colonne annee qui n'a rien à faire là puisqu'elle est une propriété de l'entité jour.
Par ailleurs, tout cela s'appuie sur une tel fatras non maîtrisé qu'il devient difficile d'y appliquer un raisonnement rationnel.
Comme tu as fait l'effort de nous fournir les CREATE TABLE et les requêtes d'INSERT pour un jeu d'essai, je vais jouer le jeu, ce soir, en me créant une base test pour les requêtes.
ĝis.
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne
Première analyse succinte, par exemple, la table jours devrait plutôt être comme ceci:
En effet pourquoi t'embêter avec une colonne année et te priver des avantages d'une colonne de type DATE ?
J'observe que de nombreuse colonnes sont de type CHAR ou VARCHAR pas du tout adaptés aux contenus que révèlent les INSERT.
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne
cet exemple que j'ai donne n'est que pour apprendre les jointures entre tables, a chaque fois je mets un exemple, je le comprends, je pass a un autre, c'est pour cela je change pas la structure des tables, j'utilise les meme tables pour plusieurs exemple, c'est le cas pour extraire les etudiants qui ont passe l'examen pour tel jour telle annee
Hors ligne
Je ne vois pas ce que ça change par rapport aux remarques que j'ai faites.
Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy
Hors ligne