Archives par étiquette : sql

Création d’un état avec niveau de regroupement

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.

etat-niveau-regroup1

avec PhpMyAdmin