Probleme de jointure innoDB

Répondre
Sammuel
Sammuel
Déconnecté
Salut,

Désolé de vous déranger avec mes problèmes de requêtes, mais je n'arrive pas à en faire fonctionner une qui peut paraître toute simple ! Et j'aurais besoin de votre aide pour comprendre pourquoi cela ne veut pas fonctionner !

Ma BDD test se trouve ici :
http://www.lephpfacile.com/wall/wall-1520.php
... avec quelques enregistrements.

Quelques précisions :
La table categorie 3 liste toutes les sous catégories de la catégorie 2.
La table categorie 2 liste toutes les sous catégories de la catégorie 1.
La table categorie 1 liste toutes les catégories générales.

Chaque enregistrement de la categorie 2 appartient obligatoirement à une (et une seule) categorie 1.
Chaque enregistrement de la categorie 3 appartient obligatoirement à une (et une seule) categorie 2. Mais un enregistrement de la categorie_2 n'a pas forcément de lien avec la categorie_3 ! Donc un enregistrement de la categorie_2 peut ne pas avoir de sous catégorie (categorie_3).

Un article appartient obligatoirement à une categorie 2 et peut appartenir à une categorie 3.

Un article ayant un status égal à 0 signifie qu'il est activé. Si il est égal à 1, c'est qu'il est désactivé et qu'il ne sera pas pris en compte, afficher sur le net.

Ma requête actuelle... qui ne fonctionne pas :
  1. SELECT categorie_1.nom AS categorie_1_nom,categorie_2.nom AS categorie_2_nom,COUNT(article.id) AS total
  2. FROM article
  3. LEFT JOIN categorie_3 ON article.categorie_3_id
  4. LEFT JOIN categorie_2 ON article.categorie_2_id
  5. LEFT JOIN categorie_1 ON categorie_2.categorie_1_id
  6. WHERE article.status = '0'
  7. GROUP BY categorie_1,categorie_2,categorie_3
  8. ORDER BY categorie_1,categorie_2,categorie_3 ASC 


J'ai essayé de m'inspirer de la requete de LupusMic qu'il m'a proposé dans mon précédent post, mais cela ne veut pas fonctionner.

J'ai l'impression que MYSQL n'arrive pas à faire le lien entre les tables !

Merci pour votre aide smiley
mojorisin
mojorisin
Déconnecté
echo ’16i[q]sa[ln0=aln100%Pln100/snlbx]sbA0D4D465452snlbxq’|dc
Salut,
il te faut mettre une opérande pour tes jointures avec ON.
LEFT JOIN table2 ON table1.id=table2.fki_id

ou si les noms de colonne sont identiques dans chaque table utiliser le mot clé USING.
Sammuel
Sammuel
Déconnecté
Non justement, normalement, je ne dois pas en avoir besoin, car j'utilise innoDB et donc avec les clé étrangères (FOREIGN KEY), les liens entre les tables devraient se faire automatiquement !

Sinon le problème n'est pas du au nom des colonnes ! car je les ai toutes rennomées en utilisant AS dans la requete. Et j'ai le meme probleme.
LA GLOBULE
LA GLOBULE
Déconnecté
111 111 111 x 111 111 111 = 12 345 678 987 654 321
Attention, les clés étrangères ne sont pas une conséquence de l'utilisation d'innoDB.

Tu les as créé comment tes clés étrangères ?

Et pour moi, tu dois quand même spécifier l'attribut sur lequel tu JOIN, ca parait logique. Sinon, avec ton raisonnement, tes tables seraient condamnées à joiner les autres que sur leurs clé primaire / étrangères.
Sammuel
Sammuel
Déconnecté
Voila comment j'ai procédé :

Au départ, toutes mes tables étaient de type MyISAM. J'ai donc :
* converti chaque table MyISAM en innoDB en faisant : "ALTER TABLE `nom_table` SET TYPE=InnoDB;"
* vidé toutes les tables
* exporté les structures de toutes les tables avant de les supprimer. Depuis le fichier SQL exporté, j'ai ajouté un FOREIGN KEY ou cela était necessaire.
* importé toutes les structures
* importé toutes les données
LA GLOBULE
LA GLOBULE
Déconnecté
111 111 111 x 111 111 111 = 12 345 678 987 654 321
Enfin bref, clés étrangères ou pas, tu dois spécifier les champs sur lesquels tu JOIN.
Sammuel
Sammuel
Déconnecté
Oki merci LA GLOBULE smiley

Donc, je n'ai pas a modifié les requetes que j'utilisais avec MyISAM !

Et, quand on utilises innoDB, c'est surtout coté MYSQL que ca change quelque chose. Ca ne change en rien aux requêtes que l'on utilisait sous MyISAM. Je vais continuer à me renseigner sur innoDB !
LupusMic
LupusMic
Déconnecté
Développeur récurrent, procédural et relationnel.
(La Globule) Non, Lorsque les tables sont liées par des clés, tu indiques la clé primaire sur laquelle tu veux joindre.

Pour t'en convaincre, demande à explain ce qu'il en pense :)

(Sammuel) Ça veut dire quoi, « elle ne marche pas » ? Message d'erreurs ? Les données fournies ne sont pas celles attendues ?
LA GLOBULE
LA GLOBULE
Déconnecté
111 111 111 x 111 111 111 = 12 345 678 987 654 321
LupusMic, cela m'intéresse : quand tu as une clé étrangère, tu peux te passer du ON ou du USING ? Comment MySQL comprend sur quel champ tu veux faire la jointure ? (rien ne m'oblige à faire une jointure sur une clé).
Sammuel
Sammuel
Déconnecté
LupusMic > Merci pour ta réponse ! Car j'avais un gros doute !

Sinon, la requete me retourne une erreur :
#1054 - Unknown column 'categorie_1' in 'order clause'

Pourtant, j'ai bien utilisé les clés étrangères pour lier les différentes tables ! Et je me suis basé sur la requête que tu m'avais indiqué sur mon autre post.
LA GLOBULE
LA GLOBULE
Déconnecté
111 111 111 x 111 111 111 = 12 345 678 987 654 321
La doc MySQL dit :

Notez que les clés étrangères SQL sont utilisées pour assurer la cohérence des données, et non pas pour joindre des tables. Si vous voulez obtenir des résultats de tables multiples dans une commande SELECT, vous devez le faire avec une jointure.


Donc moi aussi j'ai un doute sur votre truc :)
Sammuel
Sammuel
Déconnecté
Concernant l'erreur SQL, c'est réglé ! J'ai oublié d'indiquer tous les éléments dans GROUP BY/ORDER.

  1. SELECT categorie_1.nom AS categorie_1_nom,categorie_2.nom AS categorie_2_nom,COUNT(article.id) AS total
  2. FROM article
  3. LEFT JOIN categorie_3 ON article.categorie_3_id
  4. LEFT JOIN categorie_2 ON article.categorie_2_id
  5. LEFT JOIN categorie_1 ON categorie_2.categorie_1_id
  6. WHERE article.status = '0'
  7. GROUP BY categorie_1.nom,categorie_2.nom
  8. ORDER BY categorie_1.nom,categorie_2.nom ASC 


Cette requête, telle qu'elle, fonctionne mais elle me retourne un n'importe quoi smiley

Elle mélange les catégories 1 et 2. Et elle retourne le meme total pour toutes les catégories principales (categorie_1).

Si tu pouvais jeter un œil a tout ça, LupusMic, ce serait super sympa ! smiley
Sammuel
Sammuel
Déconnecté
Je n'ai toujours pas réussi a faire fonctionner la requête en faisant une jointure sur les clés étrangères des différentes tables. Je ne pense pas que ce soit possible d'ailleur !

Donc, je vais garder ma bonne vieille requête, le temps d'en trouver une meilleur smiley (la requête que j'utilisais sous MyISAM).
LupusMic
LupusMic
Déconnecté
Développeur récurrent, procédural et relationnel.
(La Globule) Tu as raison en fait, la clé n'est pas utilisé pour la jointure :
  1. +----+-------------+----------+-------+---------------+-----------+---------+------+------+----------------------------------------------+
  2. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  3. +----+-------------+----------+-------+---------------+-----------+---------+------+------+----------------------------------------------+
  4. | 1 | SIMPLE | voitures | index | NULL | modele_id | 5 | NULL | 1 | Using index; Using temporary; Using filesort |
  5. | 1 | SIMPLE | modeles | ALL | NULL | NULL | NULL | NULL | 1 | |
  6. | 1 | SIMPLE | marques | ALL | NULL | NULL | NULL | NULL | 1 ||
  7. +----+-------------+----------+-------+---------------+-----------+---------+------+------+----------------------------------------------+ 


Je traduisais mal « on » :( mea culpa. Bref, il faut effectivement spécifier une condition complète.

  1. select marques.id as marque_id , marques.marque as marque , modeles.id as modele_id , modeles.modele as modele , count(voitures.id) as total from voitures left join modeles on voitures.modele_id = modeles.id left join marques on modeles.marque_id = marques.id group by marque, modele order by marque, modele asc; 


Avec le explain qui indique bien l'usage des clés :
  1. +----+-------------+----------+--------+---------------+-----------+---------+-------------------------+------+----------------------------------------------+
  2. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  3. +----+-------------+----------+--------+---------------+-----------+---------+-------------------------+------+----------------------------------------------+
  4. | 1 | SIMPLE | voitures | index | NULL | modele_id | 5 | NULL | 1 | Using index; Using temporary; Using filesort |
  5. | 1 | SIMPLE | modeles | eq_ref | PRIMARY | PRIMARY | 4 | test.voitures.modele_id | 1 | | 
  6. | 1 | SIMPLE | marques | eq_ref | PRIMARY | PRIMARY | 4 | test.modeles.marque_id | 1 | |
  7. +----+-------------+----------+--------+---------------+-----------+---------+-------------------------+------+----------------------------------------------+ 
Répondre
Accès rapide :

Remonter Remonter
L'éditeur javascript - CSS - Gentoo - Tutoriaux PHP - Tutoriels PHP - Php