Requete ok sous PHP4, et ne fonctionne plus sous PHP5

Répondre
Sammuel
le 05/03/2008 à 16:43
Sammuel
Salut ! C'est encore moi smiley

J'ai une requête qui ne veux plus fonctionner sous PHP5 ! Sous PHP4, elle fonctionnait très bien ! meme si je me demandais comment MYSQL pouvait s'y retrouver avec ^^

La requête est la suivante :
SELECT marque.idmarque,marque.marque,modele.idmodele,modele.modele,COUNT(voiture.idvoiture) AS total
FROM marque,modele
LEFT JOIN voiture ON voiture.idmarque = marque.idmarque
WHERE marque.idmarque = modele.idmarque
GROUP BY marque.marque,modele.modele
ORDER BY marque.marque,modele.modele ASC


Les tables :
Marque (idmarque / marque)
1 Renault
2 Citroen
3 Peugeot
...

Modele (idmodele / idmarque / modele)
1 1 Clio
2 1 Scenic
3 2 Xsara
4 2 Saxo
5 3 306
...

Voiture (idvoiture / idmarque / idmodele / serie)
1 1 1 Clio 1
2 1 1 Clio 2
3 3 5 306 phase 1
4 3 5 306 phase 2
...

PS : J'ai inclus l'idmarque dans la table voiture pour éviter de faire trop de jointures entre les tables, car il y aura beaucoup d'enregistrements dans cette table... + d'1 million


Voyez vous un problème dans la requête ? car MYSQL me retourne cette erreur :
#1054 - Unknown column 'marque.idmarque' in 'on clause'


Apparemment, MYSQL n'arrive pas à faire de lien entre la table 'marque' et 'voiture' dans le LEFT JOIN. Pourtant sous PHP4, ca fonctionné ^^

Peut être que je dois activer quelque chose dans le php.ini pour que ça fonctionne ? smiley
LA GLOBULE
le 05/03/2008 à 16:56
LA GLOBULE
Ben tu as juste une erreur SQL, ca n'a rien à voir avec la version de PHP.

Et l'erreur est simple : MySQL ne connait pas le champ "marque.idmarque".
Ensuite, il faudrait voir la structure réelle de tes tables et non une explication en francais de ton schéma de base. Genre un dump de phpmyadmin sur la structure des tables.
Tu n'aurais pas une faute d'orthographe sur le nom de ton champ ? (genre il ne serait pas écrit pareil en base et dans la requête).
Sammuel
le 05/03/2008 à 17:23
Sammuel
non aucune erreur d'accent.

Avant, j'utilisais Easyphp 1.7 en local sous windows avec :
Apache 1.3.27
PHP 4.3.3
Phpmyadmin 2.5.3
Mysql 4.0.15

Et quand j'exporte la bdd, cela me retourne :
CREATE TABLE `marque` (
`idmarque` int(2) NOT NULL auto_increment,
`marque` varchar(50) default NULL,
PRIMARY KEY (`idmarque`)
) TYPE=MyISAM AUTO_INCREMENT=5 ;


Aujourd'hui, j'utilise WAMP5 en local avec :
Apache 2.2.6
PHP 5.2.5
MYSQL 5.0.45

Et quand j'exporte la bdd, cela me retourne :
CREATE TABLE `marque` (
`idmarque` int(2) NOT NULL auto_increment,
`marque` varchar(50) default NULL,
PRIMARY KEY (`idmarque`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;


Donc peut etre que le probleme est lié au CHARSET ?? car maintenant, sous WAMP, j'ai une colonne 'Interclassement' avec 'latin1_swedish_ci' de mentionner dedans.
Sammuel
le 05/03/2008 à 17:48
Sammuel
Sous WAMP5, j'ai fait un test d'importation de la bdd en latin1, en UTF8, mais ça ne change rien. Idem quand je spécifie le format d'importation en MYSQL 4.

La requête affiche toujours la même erreur.

J'ai essayé de renommé la table, puis de la re renommer 'marque'. Ca ne change rien.

C'est bien MYSQL qui n'arrive pas à faire le lien entre la table voiture et marque.
Sammuel
le 05/03/2008 à 17:52
Sammuel
Je viens de trouver ca :
http://www.oscommerce-fr.info/faq/qa_info.php?qID=198

Je continue a chercher ;)
Sammuel
le 05/03/2008 à 17:56
Sammuel
tss...

J'ai simplement ajouté des () dans FROM et ca fonctionne :
SELECT marque.idmarque,marque.marque,modele.idmodele,modele.modele,COUNT(voiture.idvoiture) AS total
FROM (marque,modele)
LEFT JOIN voiture ON voiture.idmarque = marque.idmarque
WHERE marque.idmarque = modele.idmarque
GROUP BY marque.marque,modele.modele
ORDER BY marque.marque,modele.modele ASC


mdr... je ne vois pas trop l'intéret de faire ca, mais si ca peut leur faire plaisir smiley

En tout cas, l'erreur retournée n'est pas du tout explicite !!
LupusMic
le 06/03/2008 à 01:13
LupusMic
Pourquoi limiter à 100 le nombre de marques ? N'oublie pas que la pire des optimisation, c'est celle qui créé des bogues. Si vraiment ça commence à ramer, il sera toujours temps d'optimiser.

Ta requête ne passait plus parce que MySQL 5 ne comprend pas le SQL comme le comprenait MySQL 4. D'ailleurs, je le comprends, le pauvre.

Pour comprendre ce qui se passe, il faut extraire le morceau suivant :
modele LEFT JOIN voiture ON voiture.idmarque = marque.idmarque


L'erreur retournée est parfaitement explicite. Dans ce code, MySQL fait une jointure sur les table modele et voiture. À ce moment, l'interpréteur ne connait aucune autre table. Ainsi la table marque, on connait pas. D'ailleurs, c'est une erreur de faire intervenir la table marque.

En mettant des parenthèse autour des deux tables, tu grille la priorité au left join en forçant la première jointure. Ce qui créé une table dans laquelle la colonne souhaitée dans le on clause existerait. Certes ça marche, mais question performances... j'ai des doutes sérieux.

Je repose les tables à ma convenance (pour faire des essais), et réécrit la requête que tu semble souhaiter. Au fait, dans la table voitures, le champs marque_id est malvenu. À mon avis. Et si vraiment il y a besoin d'optimiser, il faudra se poser les questions à ce moment.

create table marques (
id int(11) NOT NULL auto_increment,
marque varchar(255) default NULL,
primary key (`id`)
) engine='InnoDB' ;

create table modeles
( id int(11) NOT NULL auto_increment
, modele varchar(255) default NULL
, marque_id integer

, primary key (`id`)
, foreign key (marque_id) references marques(id)
) engine='InnoDB' ;

create table voitures
( id int(11) NOT NULL auto_increment
, label varchar(255) default NULL
, modele_id integer

, primary key (`id`)
, foreign key (modele_id) references modeles(id)
) engine='InnoDB' ;

explain
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
left join marques on modeles.marque_id
group by marque, modele
order by marque, modele asc ;


Et puis un conseil : du SQL en aveugle, c'est casse-gueule. Tu devrais lire la documentation de MySQL in extenso pour vraiment maîtriser ces arcanes (ce que je suis loin de pouvoir assurer pour moi ;) ).
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Sammuel
le 06/03/2008 à 15:51
Sammuel
Merci pour ton aide LupusMic ;)

C'est vrai que je fais du SQL a la bonne franquette même si j'essaie de limiter le nombre de requêtes et essaie de les simplifier au maximum.

J'avais l'intention d'acheter des livres à ce sujet... mais je peux surement trouver tout ce qu'il me faut sur internet !

Je vais tester ta requete, tes tables, et je te tiens au courant !
Sammuel
le 06/03/2008 à 16:23
Sammuel
J'ai oublié de préciser que j'ai toujours utilisé MyISAM comme moteur SQL. Et comme je comptais utiliser FULL TEXT pour faire une recherche au niveau du nom des voitures par exemple, ou au niveau de leurs descriptions, ça ne va pas fonctionner avec InnoDB !

La fonction recherche sur mon site est une fonction principale pour naviguer dessus (50/75% d'utilisation)... un peu comme un moteur de recherche en fait :) Donc, c'est surtout a ce niveau qu'il faut que j'optimise. Je comptais donc utiliser FULL TEXT !

Existe t'il un moyen d'optimiser une recherche via InnoDB ? à l'instar du FULL TEXT avec MyISAM ?
LA GLOBULE
le 06/03/2008 à 18:17
LA GLOBULE
Tu te contredis la : tu dis utiliser MyISAM, et tu veux faire du FULLTEXT.
Et ben justement, le FULLTEXT, c'est dispo avec MyISAM.

Donc je ne vois pas pourquoi tu parles d'innoDB la.

Ensuite, comment faire la même chose que le FULLTEXT en innoDB, ben il existe plusieurs solutions : dupliquer la table en MyISAM, ou créer un algo de recherche.
Répondre
LoadingChargement en cours