par
sadeq » 01 juil. 2009, 15:09
Bonjour,
C'est normal que tu ne puisse pas avoir les villes sans doublons dans le résultat SQL, car ta requête sélectionne au moins 2 champs. Même si tu mets un DISTINCT ou un GROUP BY cela ne changera rien car le DISTINCT est utile quand on n'a pas de détail qui distingue les lignes ayant des valeurs commune. Et le GROUP BY n'est utile que lorsqu'on veut faire des calculs.
La solution dans ton cas est d'exécuter la requête comme elle est en utilisant bien sûr un ORDER BY qui classe les lignes par ville. Puis d'afficher le résultat de cette requête dans la table HTML en évitant les doublons de villes et en affichant la ville dans une cellule qui fusionne toutes les lignes qui affichent les activités ce cette ville. Pour cela il suffit d'utiliser un ROWSPAN dans chaque cellule qui affiche une ville.
Voici comment réaliser cette solution:
<p>Voici un exemple de table HTML qui fait un regroupement de lignes autour d'une cellule fusionnée verticalement (ROWSPAN)</p>
<table border="1">
<tr><td rowspan="4">Ville 1</td></tr>
<tr><td>Activité 1</td></tr>
<tr><td>Activité 2</td></tr>
<tr><td>Activité 3</td></tr>
<tr><td rowspan="3">Ville 2</td></tr>
<tr><td>Activité 1</td></tr>
<tr><td>Activité 2</td></tr>
</table>
<p>Et voici la même table produite par PHP depuis une source de données tableau (Array)</p>
<table border="1">
<?php
// Source de données pour affichage
$data = array(
'ville 1' => array('Activité 1', 'Activité 2', 'Activité 3'), // Les activités sont regroupées par ville
'ville 2' => array('Activité 1', 'Activité 2'),
);
// Affichage des données de la source $data
foreach($data as $ville=>$tab_activités){ // ROWSPAN = le nombre de lignes à fusionner = le nombre d'activités + une ligne pour la ville
echo sprintf('<tr><td rowspan="%d">%s</td></tr>', count($tab_activités)+1, $ville);
foreach($tab_activités as $activité){
echo sprintf('<tr><td>%s</td></tr>', $activité);
}
}
?>
</table>
<p>Et voici la même table produite par PHP depuis une source de base de données (SQL)</p>
<table border="1">
<?php
// Source de données pour affichage
$sql = "SELECT ville, activite FROM matable ORDER BY ville"; // liste des villes et activités classée par ville -+
$result = mysql_db_query('test', $sql, mysql_connect('localhost', 'root')) or die (mysql_error());
$data = array(); //tableau de données à produire pour l'affichage
while ($result && $row = mysql_fetch_array($result)){
$ville = $row['ville']; // le champ ville servira comme index sans doublons pour le tableau $data
$data[$ville][] = $row['activite']; //le champ activite sera stocké dans chaque index ville comme sous-tableau
}
mysql_close();
// Affichage des données de la source $data
if (count($data)>0){
foreach($data as $ville=>$tab_activités){
echo sprintf('<tr><td rowspan="%d">%s</td></tr>', count($tab_activités)+1, $ville);
if (count($tab_activités)>0){
foreach($tab_activités as $activité){
echo sprintf('<tr><td>%s</td></tr>', $activité);
}
}
else { echo '<tr><td>Aucune activité trouvée !</td></tr>'; }
}
}
else { echo '<tr><td>Aucune ville trouvée !</td></tr>'; }
?>
</table>
<p>ANNEXE: Voici le code SQL de la base de données de test</p>
<pre>
-- phpMyAdmin SQL Dump
-- version 3.1.3
-- http://www.phpmyadmin.net
--
-- Serveur: localhost
-- Généré le : Mer 01 Juillet 2009 à 14:53
-- Version du serveur: 5.1.32
-- Version de PHP: 5.2.9-1
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
--
-- Base de données: `test`
--
-- --------------------------------------------------------
--
-- Structure de la table `matable`
--
CREATE TABLE IF NOT EXISTS `matable` (
`ville` varchar(255) NOT NULL,
`activite` varchar(255) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Contenu de la table `matable`
--
INSERT INTO `matable` (`ville`, `activite`) VALUES
('Aix-en-Provence', 'Agence de voyages d''affaires'),
('Aix-en-Provence', 'Conseil en management de l''innovation'),
('Aix-en-Provence', 'Courtage en prêt professionnel'),
('Aix-en-Provence', 'Economie d''Impôt, Création de Valeurs - Patrimoine'),
('Aix-en-Provence', 'Formation professionnelle'),
('Aix-en-Provence', 'Formation, conseil'),
('Aix-en-Provence', 'Gestion de Patrimoine, conseils et courtage assurances et financier'),
('Aix-en-Provence', 'Prestations de services informatiques pour aider les chefs d entreprises '),
('Nice', 'Agence Conseil en communication'),
('Nice', 'Agence de business development'),
('Nice', 'Agence de Voyages'),
('Tunis, Tunisie', 'Affaires internationales');
</pre>
Bonjour,
C'est normal que tu ne puisse pas avoir les villes sans doublons dans le résultat SQL, car ta requête sélectionne au moins 2 champs. Même si tu mets un DISTINCT ou un GROUP BY cela ne changera rien car le DISTINCT est utile quand on n'a pas de détail qui distingue les lignes ayant des valeurs commune. Et le GROUP BY n'est utile que lorsqu'on veut faire des calculs.
La solution dans ton cas est d'exécuter la requête comme elle est en utilisant bien sûr un ORDER BY qui classe les lignes par ville. Puis d'afficher le résultat de cette requête dans la table HTML en évitant les doublons de villes et en affichant la ville dans une cellule qui fusionne toutes les lignes qui affichent les activités ce cette ville. Pour cela il suffit d'utiliser un ROWSPAN dans chaque cellule qui affiche une ville.
Voici comment réaliser cette solution:
[php]
<p>Voici un exemple de table HTML qui fait un regroupement de lignes autour d'une cellule fusionnée verticalement (ROWSPAN)</p>
<table border="1">
<tr><td rowspan="4">Ville 1</td></tr>
<tr><td>Activité 1</td></tr>
<tr><td>Activité 2</td></tr>
<tr><td>Activité 3</td></tr>
<tr><td rowspan="3">Ville 2</td></tr>
<tr><td>Activité 1</td></tr>
<tr><td>Activité 2</td></tr>
</table>
<p>Et voici la même table produite par PHP depuis une source de données tableau (Array)</p>
<table border="1">
<?php
// Source de données pour affichage
$data = array(
'ville 1' => array('Activité 1', 'Activité 2', 'Activité 3'), // Les activités sont regroupées par ville
'ville 2' => array('Activité 1', 'Activité 2'),
);
// Affichage des données de la source $data
foreach($data as $ville=>$tab_activités){ // ROWSPAN = le nombre de lignes à fusionner = le nombre d'activités + une ligne pour la ville
echo sprintf('<tr><td rowspan="%d">%s</td></tr>', count($tab_activités)+1, $ville);
foreach($tab_activités as $activité){
echo sprintf('<tr><td>%s</td></tr>', $activité);
}
}
?>
</table>
<p>Et voici la même table produite par PHP depuis une source de base de données (SQL)</p>
<table border="1">
<?php
// Source de données pour affichage
$sql = "SELECT ville, activite FROM matable ORDER BY ville"; // liste des villes et activités classée par ville -+
$result = mysql_db_query('test', $sql, mysql_connect('localhost', 'root')) or die (mysql_error());
$data = array(); //tableau de données à produire pour l'affichage
while ($result && $row = mysql_fetch_array($result)){
$ville = $row['ville']; // le champ ville servira comme index sans doublons pour le tableau $data
$data[$ville][] = $row['activite']; //le champ activite sera stocké dans chaque index ville comme sous-tableau
}
mysql_close();
// Affichage des données de la source $data
if (count($data)>0){
foreach($data as $ville=>$tab_activités){
echo sprintf('<tr><td rowspan="%d">%s</td></tr>', count($tab_activités)+1, $ville);
if (count($tab_activités)>0){
foreach($tab_activités as $activité){
echo sprintf('<tr><td>%s</td></tr>', $activité);
}
}
else { echo '<tr><td>Aucune activité trouvée !</td></tr>'; }
}
}
else { echo '<tr><td>Aucune ville trouvée !</td></tr>'; }
?>
</table>
<p>ANNEXE: Voici le code SQL de la base de données de test</p>
<pre>
-- phpMyAdmin SQL Dump
-- version 3.1.3
-- http://www.phpmyadmin.net
--
-- Serveur: localhost
-- Généré le : Mer 01 Juillet 2009 à 14:53
-- Version du serveur: 5.1.32
-- Version de PHP: 5.2.9-1
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
--
-- Base de données: `test`
--
-- --------------------------------------------------------
--
-- Structure de la table `matable`
--
CREATE TABLE IF NOT EXISTS `matable` (
`ville` varchar(255) NOT NULL,
`activite` varchar(255) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Contenu de la table `matable`
--
INSERT INTO `matable` (`ville`, `activite`) VALUES
('Aix-en-Provence', 'Agence de voyages d''affaires'),
('Aix-en-Provence', 'Conseil en management de l''innovation'),
('Aix-en-Provence', 'Courtage en prêt professionnel'),
('Aix-en-Provence', 'Economie d''Impôt, Création de Valeurs - Patrimoine'),
('Aix-en-Provence', 'Formation professionnelle'),
('Aix-en-Provence', 'Formation, conseil'),
('Aix-en-Provence', 'Gestion de Patrimoine, conseils et courtage assurances et financier'),
('Aix-en-Provence', 'Prestations de services informatiques pour aider les chefs d entreprises '),
('Nice', 'Agence Conseil en communication'),
('Nice', 'Agence de business development'),
('Nice', 'Agence de Voyages'),
('Tunis, Tunisie', 'Affaires internationales');
</pre>
[/php]