Dans un rapport Microsoft Access, il est possible de créer des niveaux de regroupement sur des champs d'une table ou d'une requête. Comment réaliser ces mêmes états sous ZF2 / MySql avec TcPdf ?
Exemple concret
Soit 2 tables, `eleves` et `tarifs` définies de la manière suivante :
Table `eleves` :
CREATE TABLE IF NOT EXISTS `t_eleves` ( `eleveId` int(11) NOT NULL AUTO_INCREMENT, `tarifId` int(11) NOT NULL DEFAULT "0"', `nom` varchar(30) COLLATE utf8_unicode_ci NOT NULL, `prenom` varchar(30) COLLATE utf8_unicode_ci NOT NULL, `adresseL1` varchar(38) COLLATE utf8_unicode_ci NOT NULL, `adresseL2` varchar(38) COLLATE utf8_unicode_ci NOT NULL, `codePostal` varchar(5) COLLATE utf8_unicode_ci NOT NULL, `commune` varchar(32) COLLATE utf8_unicode_ci NOT NULL, `dateN` date NOT NULL, `dateCreation` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `dateModification` datetime NOT NULL DEFAULT '1900-01-01 00:00:00', `dateInscription` datetime NOT NULL DEFAULT '1900-01-01 00:00:00', `inscrit` tinyint(1) unsigned NOT NULL DEFAULT '1', `selection` tinyint(1) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`eleveId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Table `tarifs` :
CREATE TABLE IF NOT EXISTS `t_tarifs` ( `tarifId` int(11) NOT NULL AUTO_INCREMENT, `montant` decimal(10,2) NOT NULL DEFAULT '0.00', `nom` varchar(48) COLLATE utf8_unicode_ci NOT NULL, `rythme` int(4) NOT NULL DEFAULT '1', `grille` int(4) NOT NULL DEFAULT '1', PRIMARY KEY (`tarifId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
On souhaite créer un état qui affiche la liste des élèves par tarif, avec un sous-total à la fin de chaque groupe de tarifs, et le total général à la fin de l'état.
Création de la requête
On a 3 parties dans la requête :
- le détail de chaque groupe contenant les élèves
- le pied de chaque groupe contenant le nombre d'élèves du groupe et le montant total du groupe
- la marge du bas contenant le nombre total d'élèves et le total général
On codera 'd' pour 'détail', 'p' pour 'pied', 'g' pour 'groupe', 'm' pour 'marge'. On remarquera que le codage respecte l'ordre d'affichage :
- 'g' avant 'm'
- 'd' avant 'p'
On obtient un résultat convenable par :
SELECT nom, prenom, montant FROM ( SELECT 'g' c1, t.tarifId c2, 'd' c3, e.nom, e.prenom, t.montant FROM t_eleves e INNER JOIN t_tarifs t ON e.tarifId=t.tarifId UNION SELECT 'g' c1, t.tarifId c2, 'p' c3, concat('Pour ', t.nom), count(eleveId), sum(t.montant) FROM t_eleves e INNER JOIN t_tarifs t ON e.tarifId=t.tarifId GROUP BY t.tarifId UNION SELECT 'm' c1, '' c2, '' c3, 'Total général', count(eleveId), sum(t.montant) FROM t_eleves e INNER JOIN t_tarifs t ON e.tarifId=t.tarifId ) u ORDER BY c1,c2,c3,1,2
Pour la mise en page, on aura sans doute intérêt à afficher les colonnes c1, c2 et c3.