j'ai une table avec 2 colonnes categ et sous_categ, il peut avoir plusieurs fois la même info dans categ et sous.
Je voudrais classé par categ avec celui qui a le plus de sous_categ au moins.
je ne voie pas comment faire.
$recp_categ = $bdd->query("SELECT DISTINCT categ FROM categorie where id != 1 ORDER BY sous_categ DESC");
while ($recp_catego = $recp_categ->fetch())
{
$categnom = $recp_catego['categ'];
echo "<h3>".substr($categnom, 0, 40)."</h3><ul>";
$recp_categ2 = $bdd->query("SELECT * FROM categorie where id != 1 AND categ = '$categnom' ORDER BY sous_categ");
while ($recp_scateg2 = $recp_categ2->fetch())
{
$socateg = $recp_scateg2['sous_categ'];
echo '<li><a href="Recherche-Astuce-Tuto&categorie='.$categnom.'&socategorie='.$socateg.'">'.substr($socateg, 0, 34).'</a></li>';
}
skuti, oui je pense que ça doit être avec modif SQL mais je suis pas a ton niveau, la j'ai rien compris ton code et me marque erreur:
Fatal error: Uncaught Error: Call to a member function fetch() on bool
<div class="col_7">
<h2>Rechercher selon les Catégories</h2>
</div>
<?php $num = 1; ?>
<div class="col_1">
<?php
$recp_categ = $bdd->query("SELECT DISTINCT c.categ
FROM categorie AS c
INNER JOIN categorie AS subc ON subc.categ = c.categ
WHERE c.id != 1
ORDER BY COUNT(subc.sous_categ) DESC");
//$recp_categ = $bdd->query("SELECT DISTINCT categ FROM categorie where id != 1 ORDER BY sous_categ DESC");
while ($recp_catego = $recp_categ->fetch())
{
$categnom = $recp_catego['categ'];
echo "<h3>".substr($categnom, 0, 40)."</h3><ul>";
$recp_categ2 = $bdd->query("SELECT * FROM categorie where id != 1 AND categ = '$categnom' ORDER BY sous_categ");
while ($recp_scateg2 = $recp_categ2->fetch())
{
$socateg = $recp_scateg2['sous_categ'];
echo '<li><a href="Recherche-Astuce-Tuto&categorie='.$categnom.'&socategorie='.$socateg.'">'.substr($socateg, 0, 34).'</a></li>';
}
if ( $num == 1)
{
echo "</div> <div class='col_1'>";
$num = 0;
}
$num++;
} </div><!-- End 5 columns container --> </li><!-- End 5 columns Item -->
ma table:
actuellement c'est comme ça mais je voudrais classé de la catégorie qui a le plus de sous catégorie pour ne pas avoir du vide comme maintenant
Je vais répondre en deux temps. D'abord pour faire fonctionner ton modèle existant, puis en corrigeant ton modèle pour qu'il soit plus propre.
Donc, avec ton modèle actuel, je te propose de fonctionner avec cette requête :
SELECT
C.categ,
C.sous_categ
FROM
categorie C
INNER JOIN (
-- Nombre de sous-catégories par catégorie
SELECT categ, COUNT(*) AS nb_sous_categ
FROM categorie
WHERE id != 1
GROUP BY categ
) N
ON C.categ = N.categ
ORDER BY
N.nb_sous_categ DESC,
C.sous_categ ASC
Il y a une sous-requête qui compte le nombre de sous-catégories par catégorie, et qui nous permet de trier le résultat global.
Il faut retirer ces histoires de boucles imbriquées, qui sont lentes et peuvent même planter le serveur si beaucoup de catégories à traiter.
Côté PHP cela donnerait :
<div class="col_7">
<h2>Rechercher selon les Catégories</h2>
</div>
<div class="col_1">
<?php
$premiereLigne = true;
$categoriePrecedente = '';
$requete = $bdd->query('
SELECT
C.categ,
C.sous_categ
FROM
categorie C
INNER JOIN (
-- Nombre de sous-catégories par catégorie
SELECT categ, COUNT(*) AS nb_sous_categ
FROM categorie
WHERE id != 1
GROUP BY categ
) N
ON C.categ = N.categ
ORDER BY
N.nb_sous_categ DESC,
C.sous_categ ASC'
);
$elements = $requete->fetchAll();
foreach( $elements as $element ) {
// Si c'est une catégorie non encore traitée
if( $categoriePrecedente != $element['categ'] ) {
// Si ce n'est pas la première ligne
if( !$premiereLigne ) {
// On ferme le ul précédent
?>
</ul>
<?php
}
// On affiche le titre de la catégorie
?>
<h3><?= $element['categ']; ?></h3>
<ul>
<?php
}
// Dans tous les cas on affiche la sous-catégorie
?>
<li><a href="Recherche-Astuce-Tuto&categorie=<?= $element['categ']; ?>&socategorie=<?= $element['sous_categ']; ?>"></a></li>
<?php
$premiereLigne = false;
$categoriePrecedente = $element['categ'];
}
?>
</ul>
</div>
Maintenant, ton modèle n'est pas propre du tout ... tu devrais le changer.
Une solution simple, avec deux tables :
categorie ( id [pk], libelle )
scategorie ( id [pk], id_categorie [fk], libelle )
La requête pour générer le menu devient :
SELECT
C.id AS idc,
C.libelle AS categ,
SC.id AS idsc,
SC.libelle AS sous_categ
FROM
categorie C
INNER JOIN scategorie SC
ON C.id = SC.id_categorie
INNER JOIN (
-- Nombre de sous-catégories par catégorie
SELECT id, COUNT(*) AS nb_sous_categ
FROM categorie
GROUP BY id
) N
ON C.id = N.id
ORDER BY
N.nb_sous_categ DESC,
SC.libelle ASC
Et le code PHP est identique. Sauf que tu peux passer les id au lieu des noms dans le lien <a>.
Une autre solution plus subtile avec une auto référence sur une seule table :
categorie( id [pk], id_parent [fk], libelle )
La requête serait :
SELECT
C.id AS idc,
C.libelle AS categ,
SC.id AS idsc,
SC.libelle AS sous_categ
FROM
categorie C
INNER JOIN categorie SC
ON C.id = SC.id_parent
INNER JOIN (
-- Nombre de sous-catégories par catégorie
SELECT id_parent, COUNT(*) AS nb_sous_categ
FROM categorie
WHERE id_parent IS NOT NULL
GROUP BY id_parent
) N
ON C.id = N.id
ORDER BY
N.nb_sous_categ DESC,
SC.libelle ASC
Benzouye j’essaie de modifier le script avec auto référence sur une seule table.
mais ça ne fonctionne pas, me dit qu'il ne trouve pas id_parent
<li><a href="Recherche-Astuce-Tuto" class="drop">Rechercher</a><!-- Begin 5 columns Item -->
<div class="dropdown_6columns"><!-- Begin 5 columns container -->
<div class="col_7">
<h2>Rechercher selon les Catégories</h2>
</div>
<?php $num = 1; ?>
<div class="col_1">
<?php
$premiereLigne = true;
$categoriePrecedente = '';
$requete = $bdd->query('
SELECT
C.id AS idc,
C.libelle AS categ,
SC.id AS idsc,
SC.libelle AS sous_categ
FROM
categorie C
INNER JOIN categorie SC
ON C.id = SC.id_parent
INNER JOIN (
-- Nombre de sous-catégories par catégorie
SELECT id_parent, COUNT(*) AS nb_sous_categ
FROM categorie
WHERE id_parent IS NOT NULL
GROUP BY id_parent
) N
ON C.id = N.id
ORDER BY
N.nb_sous_categ DESC,
SC.libelle ASC
');
$elements = $requete->fetchAll();
foreach( $elements as $element ) {
// Si c'est une catégorie non encore traitée
if( $categoriePrecedente != $element['categ'] ) {
// Si ce n'est pas la première ligne
if( !$premiereLigne ) {
// On ferme le ul précédent
echo "</div> <div class='col_1'>";
}
$categnom = $element['categ'];
echo "<h3>".substr($categnom, 0, 40)."</h3><ul>";
}
$socateg = $element['sous_categ'];
//Remplacement de caractère pour la réécriture du l'url htaccess $aid = $element['id']; $info = $element['titre_astuce']; $info = htmlspecialchars($info);
?>
<form method="POST" class="voirast" action="Voir_Astuce-<?php echo $aid;?>/<?php echo $info;?>">
<INPUT type="hidden" name="idanon" value="<? echo $aid;?>" />
</form>
<?php
echo '<li><a "onclick"="document.voirast.submit();">'.substr($socateg, 0, 34).'</a></li>';
$premiereLigne = false;
$categoriePrecedente = $element['categ'];
}
?>
</div><!-- End 5 columns container -->
</li><!-- End 5 columns Item -->
ps: désolé mais j'arrive pas a mettre tous le script open me bloc la page
- Edité par maxtrident 22 décembre 2020 à 11:52:27
Je n'ai pas ajouté 2 colonnes ... J'ai revu complètement la table ... Je pense que la lecture du cours MySQL peut s'avérer très utile (cf. ma signature).
Dans ma proposition il n'y a qu'une seule table avec 3 colonnes :
id, qui est l'identifiant unique de la catégorie, un entier auto incrémenté et clé primaire (ou primary key en anglais)
id_parent, qui est un entier, et doit contenir l'id de la catégorie parente pour une sous-catégorie, ou null si c'est une catégorie, c'est une clé étrangère (ou foreign key en anglais)
libelle, qui est du texte et contient le libellé de la catégorie (si id_parent est null) ou de la sous-catégorie (si id_parent est défini)
En SQL cela donne :
CREATE TABLE categorie (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
id_parent INT UNSIGNED,
libelle VARCHAR(60) NOT NULL,
FOREIGN KEY ( id_parent ) REFERENCES categorie ( id )
) Engine=InnoDB;
Ensuite cette table va contenir des données, par exemple :
ça va être super compliquer à tous modifier comme libelle à les catégories et sous-categories et des id différents, je vais essayer de faire à ta manière par la suite.
par contre comprend pas pour la création des sous catégorie comment savoir que par exemple "dessert" et dans id_parent 2 soit cuisine ?
comment faire pour ne pas afficher des catégories en double avec ton script :
SELECT
C.categ,
C.sous_categ
FROM
categorie C
INNER JOIN (
-- Nombre de sous-catégories par catégorie
SELECT categ, COUNT(*) AS nb_sous_categ
FROM categorie
WHERE id != 1
GROUP BY categ
) N
ON C.categ = N.categ
ORDER BY
N.nb_sous_categ DESC,
C.sous_categ ASC
- Edité par maxtrident 23 décembre 2020 à 16:36:08
comment savoir que par exemple "dessert" et dans id_parent 2 soit cuisine
Quand tu crées une sous-catégorie, tu mets une liste déroulante des catégories existantes avec leur id ...
SELECT id, libelle
FROM categorie
WHERE id_parent IS NULL
L'utilisateur choisi dans cette liste et défini donc l'id_parent ...
maxtrident a écrit:
ça va être super compliquer à tous modifier comme libelle à les catégories et sous-categories et des id différents
Oui, cela demande un effort de transposition ... Mais tu peux faire un enchaînement "automatique" pour tout mettre d'aplomb :
-- Création des catégories
INSERT INTO categorie ( id_parent, libelle )
SELECT DISTINCT NULL, categ
FROM categ
ORDER BY categ;
-- Création des sous-catégories
INSERT INTO categorie ( id_parent, libelle )
SELECT
N.id,
O.sous_categ
FROM
categ O
INNER JOIN categorie N
ON O.categ = N.libelle;
-- Mise à jour des astuces
UPDATE astuces A
INNER JOIN categ O
ON A.id_categorie = O.id
INNER JOIN categorie N
ON O.sous_categ = N.libelle
SET A.id_categorie = N.id;
J'ai imaginé que tu avais une table astuces avec une colonne id_categorie, mais cela doit être adapté à ton vrai modèle ...
maxtrident a écrit:
comment faire pour ne pas afficher des catégories en double avec ton script
Mon script ne devrait pas afficher de doublon, cela signifie qu'il doit y avoir des libellés de catégorie différents, genre avec un simple espace devant ou derrière le libellé. Par exemple, regarde si il n'y a pas un espace dans "Voyage / Avion" ...
Peux-tu me confirmer ce que retourne cette requête :
-- Nombre de sous-catégories par catégorie
SELECT categ, COUNT(*) AS nb_sous_categ
FROM categorie
WHERE id != 1
GROUP BY categ
Et celle-ci :
SELECT
C.categ,
C.sous_categ,
N.nb_sous_categ
FROM
categorie C
INNER JOIN (
-- Nombre de sous-catégories par catégorie
SELECT categ, COUNT(*) AS nb_sous_categ
FROM categorie
WHERE id != 1
GROUP BY categ
) N
ON C.categ = N.categ
ORDER BY
N.nb_sous_categ DESC,
C.sous_categ ASC
oui je devrais revoir le sql mais vraiment pas motivé, surtout par maque de temps et beaucoup d'autres projets avec arduino, apprendre d'autres langages pour androide...
j'avais appris le php quand c’était le site du zéro, ça date maintenant.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Pas d'aide concernant le code par MP, le forum est là pour ça :)
Site Internet : https://devst.go.yj.fr