Résultat de requête qui affiche en double

Eléphant du PHP | 331 Messages

19 déc. 2006, 23:00

Bonjour,

J'ai un problème qui concerne deux tables:

Code : Tout sélectionner

attributs_produits: id nom prix defaut ord_affiche produits_attributs: id id_produit id_attribut
Je veux une requête qui affiche tous les enregistrement de la table attributs_produits et qui sélectionnera le champ id_produit de la table produits_attributs.

Cette requête me permettra de lister tous les attributs de produit accompagné d'une case à cocher.

Cette case à cocher sera par défaut cocher pour les attributs du produit X.

Voici la requête qui me pose problème:
$sql2="SELECT ap.id, ap.nom, pa.id, pa.id_produit, pa.id_attribut FROM produits_attributs AS pa, attributs_produits AS ap ORDER BY ap.id";
$result2=mysql_query($sql2) or die("Impossible d'ouvrir la table2");

echo "<table>\n";
while ($attributs=mysql_fetch_array($result2))
{
echo "<tr>\n";
echo "<td>".stripslashes($attributs["nom"])." :</td><td><input type=\"checkbox\" name=\"attribut\" value=\"".$attributs["id"]."\"></td>\n";
echo "</tr>\n";
}
La condition du checkbox n'est pas là et c'est voulu.

Mon problème est que chacun de mes éléments de la table attributs_produits est affiché en double.

Pouvez-vous m'aider SVP?

Merci!
Modifié en dernier par stefane321 le 20 déc. 2006, 00:04, modifié 1 fois.

Eléphant du PHP | 377 Messages

19 déc. 2006, 23:41

:shock: ATTENTION ! avec la requete que tu fais, tu récupères le produit cartésien de tes deux tables (en clair: chaque ligne de l'une associé à chaque ligne de l'autre). si tu récupères deux fois chaque enregistrement c'est :
1) que tu as un enregistrement dans une table et deux dans l'autre
2) que tu as beaucoup de chance, tu peux vite mettre un serveur sur les genoux en faisant ca :)
sinon je t'avoue que je n'ai pas exactement compris ce que tu veux faire, enfin peut etre que si mais j'ai dans l'idée que tu as une table de liaison (produits_attributs) entre deux tables (attributs_produits et ???) et qu'il nous en manque une pour pouvoir bien t'aider.
si tu pouvais préciser ce serait plus facile pour nous ;)
Petit scarabée deviendra grand

Mammouth du PHP | 19672 Messages

19 déc. 2006, 23:42

Modération :
Merci d'utiliser un titre clair et qui correspond bien à ta demande.
Les titres contenant "HELP", "Aidez-moi !", "Problème" n'apportent rien à la compréhension de ton problème.
Par ailleurs, nous savons déjà par ton message que tu as besoin d'aide.

Tu peux corriger ton titre en éditant ton premier message.

Merci de prendre le temps de lire les règlements.


Second problème : écris donc du code proprement, non seulement ça facilitera la lecture pour tout le monde, mais ça la facilitera pour toi aussi.

Troisième problème : Si tu as plusieurs articles, et donc plusieurs tours de boucle while(), tu vas avoir autant de cases à cocher avec la même valeur dans l'attribut name de tes cases à cocher : et donc impossible d'en sélectionner plusieurs.

Première proposition de corrigé : on transforme cet attribut en tableau.
<?php
$sql2 = "SELECT ap.id, ap.nom, pa.id, pa.id_produit, pa.id_attribut ".
        "FROM produits_attributs AS pa, attributs_produits AS ap ".
        "ORDER BY ap.id";
$result2 = mysql_query($sql2) or die("Impossible d'exécuter la requête.<br />\nMySQL a retourné : \"". mysql_error() ."\"");
?>
<table>
<?php
while(false != ($attributs = mysql_fetch_array($result2)))
{
?>
  <tr>
    <td><?php echo(stripslashes($attributs["nom"])); ?> :</td>
    <td><input type="checkbox" name="attribut[]" value="<?php echo($attributs["id"]); ?>"></td>
  </tr>
<?php
}
//...
?>
</table>
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 331 Messages

20 déc. 2006, 00:09

Merci.

1- Écrire mon code plus proprement:

J'ai remarqué que tu ne fait fait affiché le html par des echo et que tu as mis la requête sur plus d'une ligne.

C'est se que tu veux dire par mettre le code plus propre?

2- Avec la solution que tu m'as suggéré j'obtient exactement le même résultat de requête.

Merci!

Eléphant du PHP | 331 Messages

20 déc. 2006, 00:18

J'avais pas vu la réponse de Shrell.

Je vais y voir!

Eléphant du PHP | 331 Messages

20 déc. 2006, 00:28

En fait,

Au départ j'ai une table de produit, une table attributs_produits et produits_attributs

Dans la table de produit je stock son id, son nom, sa description et le nom de son image.

Mes produits on des choix de format et de couleur différentes.

Alors, je me suis fait une table pour stocker les formats et choix de couleurs possible.

C'est choix son ensuite enregistré dans ma table produits_attributs.

La requête qui me pose problème me sert dans ma page d'admistration du produit.

Je veux y faire afficher tous les choix d'attribut possible et que les attributs qui ont préalablement été attitré au produit soit sélectionné pour que l'utilisateur voit les attribus déjà enregistré et puisse choisir de changer les attributus du produis ou non.

J'espère que mon explication est compréhensible :roll:

Mammouth du PHP | 19672 Messages

20 déc. 2006, 08:20

Question : exécute ta requête directement dans phpMyAdmin et vérifie si les enregistrements ne seraient pas également en double dans ta base :-k
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 331 Messages

20 déc. 2006, 17:06

Dans chacune de mes table les enregistrement sont unique.

Table attributs_produits:

Code : Tout sélectionner

id nom prix defaut ord_affiche 1 100g 6.00 1 0 2 15g 1.00 0 0 3 Blanc 0 0 0 4 Rose 0 0 0 5 Bleu 0 0 0
Table produits_attributs:

Code : Tout sélectionner

id id_produit id_attribut 1 2 1 2 2 2 3 3 3 4 3 4
J'ai rajoué deux enregistrements depuis mon dernier post pour tester.

Si dans ma requête j'enlève toutes sélections à la table produits_attributs les résultats ne sont pas en double mais je ne peux avoir la données nécessaires pour mettre une condition qui sélectionnera mon bouton radio quand l'attributs est attitré au produits en traitement.
$sql2 = "SELECT ap.id, ap.nom ".
        "FROM attributs_produits AS ap ".
        "ORDER BY ap.id";
Si je fais ceci j'obtiens seulement les attributs du produits en traitement:
$sql2 = "SELECT pa.id, pa.id_produit, pa.id_attribut ".
      "FROM produits_attributs AS pa ".
	  "WHERE pa.id_produit=".$row["id"]." ";
Mais ceci affiche en double car il y a deux enregistrement de la table produits_attributs qui correspondent si j'enlève la clause where sa affiche en quadruple (J'ai ajouter deux enregistrement à la table):
$sql2 = "SELECT ap.id, ap.nom, pa.id, pa.id_produit, pa.id_attribut ".
      "FROM produits_attributs AS pa, attributs_produits AS ap ".
	  "WHERE pa.id_produit=".$row["id"]." ".
    "ORDER BY ap.id";
J'ai l'impression que ma clause where pause probème ou carrément la requête.

J'ai déjà vu des requêtes utilisant quelques chose du genre INNER JOIN serait-ce plus approprié??

Si oui sa marche comment INNER JOIN?

Merci encore!

Mammouth du PHP | 19672 Messages

20 déc. 2006, 18:33

Voir ceci pour les requête avec jointure.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 377 Messages

20 déc. 2006, 19:06

$sql2 = "SELECT ap.id, ap.nom, pa.id, pa.id_produit, pa.id_attribut ". 
      "FROM produits_attributs AS pa, attributs_produits AS ap ". 
      "WHERE pa.id_produit=".$row["id"]." ". 
    "ORDER BY ap.id";
cette requete t'affiche uniquement les attributs du produit sélectionné, mais chacun est associé à toutes les lignes dans attributs_produits. Ce que j'essaierais de faire:
$sql2= "SELECT ap.id, ap.nom, pa.id, pa.id_produit, pa.id_attribut ".
        "FROM produits_attributs AS pa LEFT JOIN attributs_produits AS ap ".
        "ON ap.id=pa.id_attribut WHERE pa.id_produit='".$row['id']."'";
dans ce cas tu récupères uniquement les attributs qui sont associés à ton produit.

sinon, tu peux faire la jointure dans l'autre sens, et dans ce cas tu récupèreras tous les attributs possibles, et des champs différents de NULL si ils sont effectivement cochés pour le produit choisi :
$sql2= "SELECT ap.id, ap.nom, pa.id, pa.id_produit, pa.id_attribut ".
        "FROM attributs_produits AS ap LEFT JOIN produits_attributs AS pa ".
        "ON ap.id=pa.id_attribut";
remarque bien que dans ce dernier cas on enlève la clause WHERE pour ne pas se priver des enregistrements dans la table attributs_produits qui n'ont pas d'équivalent dans la table produits_attributs.
Ensuite tu n'as plus qu'à faire une boucle, tester si la valeur est NULL ou pas et cocher ta case le cas échéant

Une dernière chose : si tu n'utilises pas encore toutes ces tables ailleurs, je ne saurai trop te recommander de renomme ta table attributs_produits en attributs tout cours, afin de bien distinguer tes tables de valeurs (produits et attributs) de tes tables de liaison (produits_attributs)
mais ca, c'est toi qui vois :)
Petit scarabée deviendra grand

Eléphant du PHP | 331 Messages

20 déc. 2006, 19:49

Bien merci à vous deux sa fonctionne avec la requête utilisant LEFT JOIN

J'ai essayé le tuto proposé par Cyrano.

J'essais en faisant copier/coller pour ensuite modifier les requêtes proposé mais il sempble y avoir une erreure de syntaxe dans les requêtes suivantes du tutoriel.

C'est se que phpmyadmin me dit.
SELECT `pers_prenom`, `pers_nom`, `tel_num`, `tel_type`
FROM `personnes` AS p
    JOIN `telephones` AS t
    ON p.pers_id = t.pers_id;

Code : Tout sélectionner

You have an error in your SQL syntax near 'ON p.pers_id = t.pers_id LIMIT 0, 30' at line 1
SELECT `pers_prenom` AS 'Prénom', `pers_nom` AS 'Nom', COUNT(`tel_id`) AS 'NbNums'
FROM `personnes` AS p
  LEFT JOIN `telephones` AS t
    ON p.pers_id = t.pers_id
GROUP BY `pers_nom`, `pers_prenom`
ORDER BY COUNT(`tel_id`) DESC;

Code : Tout sélectionner

Invalid use of group function
J'aimerais faire fonctionner le tuto pour bien comprendre.

Merci!

Mammouth du PHP | 19672 Messages

20 déc. 2006, 20:04

Pas normal : je viens de tester directement tes deux requêtes en ligne de commande dans un premier temps et avec phpMyAdmin dans un second temps : aucune erreur n'est reportée et j'ai bien les résultats attendus.....

Quelle version de MySQL tu utilises ?
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 331 Messages

20 déc. 2006, 20:19

Version MySQL 3.23.51

C'est un serveur de développemeent locale.

J'envisage de l'upgrader lorsque j'aurai le temps (chose rare)

Merci!

Stéphane

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

20 déc. 2006, 20:30

Durée d'installation de MySQL 5.0 : 5 minutes.
Temps gaspillé à réparer des bugs qui n'auraient jamais existé si tu avais mis à jour MySQL : :?:

Mammouth du PHP | 1885 Messages

20 déc. 2006, 20:39

Durée d'installation de MySQL 5.0 : 5 minutes.
Temps gaspillé à réparer des bugs qui n'auraient jamais existé si tu avais mis à jour MySQL : :?:
Ça n'a pas de prix.

Pour tout le reste, il y a master card.
La programmation est l'expression de la poésie d'un programmeur
Génération PHP