Doublons indésirables - SQL/NoSQL - Programmation
Marsh Posté le 26-10-2007 à 20:35:43
SELECT p.nom, p.dimension, p.couleur_id, mc.type FROM mot_cle mc, COUNT(*)
// la suite de ta requete
GROUP BY p.nom, p.dimension, p.couleur_id, mc.type
ORDER BY COUNT(*) DESC
Marsh Posté le 27-10-2007 à 16:53:07
Salut flo850 !
Merci
Voici ma requete modifiee avec ton aide :
SELECT p.nom, p.dimension, p.couleur_id, mc.type FROM mot_cle mc, COUNT(*) LEFT JOIN ph_fk_mcl ON mc.id = ph_fk_mcl.id_motcle LEFT JOIN photos p ON ph_fk_mcl.id_photo = p.id WHERE (mc.fr = 'amour' OR mc.en = 'amour' OR mc.fr = 'ciel' OR mc.en = 'ciel' OR mc.fr = 'femme' OR mc.en = 'femme') GROUP BY p.nom, p.dimension, p.couleur_id, mc.type ORDER BY COUNT(*) DESC;
Mais j'obtient un message d'erreur... => Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource
Tu vois ce que ça pourrait être ?
Marsh Posté le 27-10-2007 à 16:58:53
oups
c'est pas SELECT p.nom, p.dimension, p.couleur_id, mc.type FROM mot_cle mc, COUNT(*)
mais
SELECT p.nom, p.dimension, p.couleur_id, mc.type, COUNT(*) FROM mot_cle mc
Marsh Posté le 28-10-2007 à 11:51:51
sorry...
j'ai essayé différent trucs... j'aurais franchement pu y penser !
J'essaye ça !
(Rem. : en fait la requete que j'ai affiche vient d'un echo en PHP)
Marsh Posté le 28-10-2007 à 11:54:12
Voila mon echo de $query :
SELECT p.nom, p.dimension, p.couleur_id, mc.type, COUNT(*) FROM mot_cle mc LEFT JOIN ph_fk_mcl ON mc.id = ph_fk_mcl.id_motcle LEFT JOIN photos p ON ph_fk_mcl.id_photo = p.id WHERE (mc.fr = 'amour' OR mc.en = 'amour' OR mc.fr = 'ciel' OR mc.en = 'ciel' OR mc.fr = 'enfant' OR mc.en = 'enfant') GROUP BY p.nom, p.dimension, p.couleur_id, mc.type ORDER BY COUNT(*) DESC
Y'a toujours une erreur dans la requete...
Je vais un peu regardé mais si tu as une idée... !!
Marsh Posté le 28-10-2007 à 11:56:41
mysql_error() => Utilisation invalide de la clause GROUP
En fait je me demandais pourquoi il fallait mettre les 4 dans la clause GROUP... ??
Marsh Posté le 28-10-2007 à 12:25:07
il faut mettre dans la clause group toutes les colonnes qui ne sont pas dans des fonctions d'agregation ( min,max, count ,... )
par contre, je vois pas pour l'erreur
Marsh Posté le 28-10-2007 à 12:39:29
Ben moi non plus !
j'ai toujours la même erreur :
Requete :
SELECT p.nom, p.dimension, p.couleur_id, mc.type, COUNT(*)
FROM mot_cle mc
LEFT JOIN ph_fk_mcl ON mc.id = ph_fk_mcl.id_motcle
LEFT JOIN photos p ON ph_fk_mcl.id_photo = p.id WHERE (mc.fr = 'amour' OR mc.en = 'amour' OR mc.fr = 'ciel' OR mc.en = 'ciel' OR mc.fr = 'enfant' OR mc.en = 'enfant') AND (p.couleur_id = '2')
GROUP BY p.nom, p.dimension, p.couleur_id, mc.type
ORDER BY COUNT(*) DESC
Erreur : Utilisation invalide de la clause GROUP
Marsh Posté le 28-10-2007 à 13:03:34
tu peux essayer en ne mettant que p.nom dans la liste des champs et des group ?
Marsh Posté le 28-10-2007 à 13:05:36
Voili...
Requete : SELECT p.nom, COUNT(*) FROM mot_cle mc LEFT JOIN ph_fk_mcl ON mc.id = ph_fk_mcl.id_motcle LEFT JOIN photos p ON ph_fk_mcl.id_photo = p.id WHERE (mc.fr = 'amour' OR mc.en = 'amour' OR mc.fr = 'ciel' OR mc.en = 'ciel' OR mc.fr = 'enfant' OR mc.en = 'enfant') AND (p.couleur_id = '2') GROUP BY p.nom ORDER BY COUNT(*) DESC
Erreur : Utilisation invalide de la clause GROUP
Marsh Posté le 28-10-2007 à 13:21:46
avec ça, je n'ai plus d'erreur...
mais ça ne supprime pas les doublons...
et ce n'est pas trié par perinence...
SELECT p.nom, p.dimension, p.couleur_id, mc.type, COUNT(*)
FROM mot_cle mc
LEFT JOIN ph_fk_mcl ON mc.id = ph_fk_mcl.id_motcle
LEFT JOIN photos p ON ph_fk_mcl.id_photo = p.id
WHERE (mc.fr = 'amour' OR mc.en = 'amour' OR mc.fr = 'mer' OR mc.en = 'mer' OR mc.fr = 'amitie' OR mc.en = 'amitie' OR mc.fr = 'ciel' OR mc.en = 'ciel' OR mc.fr = 'enfant' OR mc.en = 'enfant' OR mc.fr = 'homme' OR mc.en = 'homme' OR mc.fr = 'femme' OR mc.en = 'femme')
GROUP BY p.nom, p.dimension, p.couleur_id, mc.type
ORDER BY p.nom
Affichage des résultats :
nom photo = 1.jpg | dim. = 124x156 | coul. = 1 | type de mot = mot-cle
nom photo = 10.jpg | dim. = 156x354 | coul. = 1 | type de mot = concept
nom photo = 10.jpg | dim. = 156x354 | coul. = 1 | type de mot = mot-cle
nom photo = 11.jpg | dim. = 145x652 | coul. = 1 | type de mot = mot-cle
nom photo = 12.jpg | dim. = 600x800 | coul. = 2 | type de mot = mot-cle
nom photo = 13.jpg | dim. = 745x254 | coul. = 1 | type de mot = mot-cle
nom photo = 14.jpg | dim. = 123x154 | coul. = 1 | type de mot = mot-cle
nom photo = 15.jpg | dim. = 143x213 | coul. = 1 | type de mot = mot-cle
nom photo = 17.jpg | dim. = 159x157 | coul. = 1 | type de mot = mot-cle
nom photo = 19.jpg | dim. = 3101x785 | coul. = 1 | type de mot = mot-cle
nom photo = 3.jpg | dim. = 258x369 | coul. = 1 | type de mot = mot-cle
nom photo = 5.jpg | dim. = 159x159 | coul. = 1 | type de mot = mot-cle
nom photo = 7.jpg | dim. = 148x358 | coul. = 2 | type de mot = mot-cle
nom photo = 8.jpg | dim. = 148x159 | coul. = 2 | type de mot = mot-cle
nom photo = 9.jpg | dim. = 354x354 | coul. = 1 | type de mot = concept
nom photo = 9.jpg | dim. = 354x354 | coul. = 1 | type de mot = mot-cle
Marsh Posté le 28-10-2007 à 13:25:00
Visiblement quand on utilise COUNT(*) dans la clause GROUP ça fait une erreur dans la clause GROUP !?!
Marsh Posté le 28-10-2007 à 14:01:36
Sorry....
Visiblement quand on utilise COUNT(*) dans la clause ORDER ça fait une erreur dans la clause GROUP !?!
Marsh Posté le 29-10-2007 à 14:05:00
dans la clause order, utilise l'alias de ton count :
Code :
|
Marsh Posté le 29-10-2007 à 17:40:01
Je vérifie tout de même... MAIS ca a l'air de bien marcher !!!!!
Marsh Posté le 29-10-2007 à 17:53:24
Un rand merci à flo850 et MagicBuzz!!
Voici à quoi ressemble ma requete maintenant.
Et, elle semble bien fonctionner !!
SELECT p.nom, p.dimension, p.couleur_id, mc.type, COUNT(*) co FROM mot_cle mc LEFT JOIN ph_fk_mcl ON mc.id = ph_fk_mcl.id_motcle LEFT JOIN photos p ON ph_fk_mcl.id_photo = p.id WHERE (mc.fr = 'homme' OR mc.en = 'homme' OR mc.fr = 'femme' OR mc.en = 'femme' OR mc.fr = 'enfant' OR mc.en = 'enfant' OR mc.fr = 'ciel' OR mc.en = 'ciel') AND (p.couleur_id = '2') GROUP BY p.nom, p.dimension, p.couleur_id, mc.type ORDER BY co
Quelqu'un pourrait-il me dire si elle semble optimale ?
Si il a encore moyen de l'améliorer ?
Marsh Posté le 30-10-2007 à 09:40:37
mise à part les LEFT OUTER JOIN qui sont loin d'être optimum et qui méritent vérification de leur réelle utilité, il n'y a pas de problème avec ta requête. Tu peux quand même rajouter tes "OR" par des "IN", ça devrait être un peu plus clair.
PS : C'est quoi l'éditeur de merde que tu utilises et qui te fait des "LEFT JOIN" sans le mot-clé "OUTER" (qui est le mot le plus important). Ou si tu n'utilises pas un GUI, quel bouquin tu utilises ? Quel éditeur ? Que j'aille poser une bombe chez eux.
Ca me fait bondir tous les 4 matins de voir des notations de jointures attrophiées au profit d'une illisibilité exemplaire
Marsh Posté le 30-10-2007 à 10:08:48
MagicBuzz a écrit : mise à part les LEFT OUTER JOIN qui sont loin d'être optimum et qui méritent vérification de leur réelle utilité, |
Ils sont inutiles et transformés en inner par les conditions dans le where
MagicBuzz a écrit :
|
Tout à fait, et j'aurais même tendance à "inverser" le sens du IN pour que cela soit limpide, genre!
Code :
|
Mais honnêtement, si tu veux optimiser "à fond" la requete je créerais une table temporaire avec les listes des valeurs et je jointerais dessus (ci dessous en syntaxe db2 à adapter en fonction du sgbd)
Code :
|
Marsh Posté le 30-10-2007 à 10:35:19
Je n'utilise pas d'éditeur MagicBuzz... Et comme je remets à MySQL après longtemps... je n'ai plus trop la méthode... Je vais chercher des infos par-ci, par-là et j'avance petit à petit... Il faut que je m'y remette une bonne fois !!!
Donc la bombe c'est chez moi qu'il va falloir la mettre !
Je pense que je vais essayer avec le IN comme ça je peux encore laisser le choix à l'user de choisir que tous les mots soient pris en compte (AND) ou au mopins un des mots (OR) !
...WHERE 'homme' IN (mc.fr, mc.en) AND ...
...WHERE 'homme' IN (mc.fr, mc.en) OR ...
Un grand merci !
J'avance bien sur mon projet grâce à vous !
(°-°)
Marsh Posté le 30-10-2007 à 10:48:08
Pourriez-vous me dire ce que vous pensez de l'utilisation de LIKE dans ma requete ?
Ca me permettrait de pouvoir utiliser _ et % pour rendre ma recherche plus sensible :
- %jardin% => prendra en compte "jardinier"
- _v_nement => "événement" remplacer les caractères accentués (et créer ma table Mot_cle en fonction)
- ...
(°-°)
Marsh Posté le 30-10-2007 à 10:54:13
Euh...
LIKE, oublie.
C'est vraiment un tueur de perfs, pour un résultat... Extrêment limité !
Recherche du côté des "TEXT INDEX" et autres (y'a pas deux SGBD qui les appelle pareil).
Ca permet d'utiliser des fonctions telles que "MATCH", "CONTAINS", "FREETEXT", etc. qui sont bien plus performantes (ça permet de faire des recherches plus naturelles, basées sur un véritable dictionnaire linguistique -donc selon les SGBD on peut même faire des requêtes sur "baker" et récupérer les lignes qui parlent de "croissants" -)
Marsh Posté le 30-10-2007 à 17:08:15
J'utilise PHP/MySQL et ce qu'on peut faire c'est des recherches en texte intégral. Mais il pratiquement pas d'options.
- On peut rechercher en mode booléens (ça m'intéresse moyen)
- On peut utiliser l'extension de requete aveugle (dans mon cas si je rentre des mots clés légèrement différent, p.ex. "homme femm" ou "homme femmes" à la place de "homme femme", le résultat est le même que si je n'avais mis que "homme" )
Ca ne laisse donc pas trop de "liberté d'erreurs" à l'utilisateur !
Marsh Posté le 30-10-2007 à 17:18:59
port'nawak
tu n'as pas du bien lire la doc: http://dev.mysql.com/doc/refman/5. [...] olean.html
Après c'est à toi de correctement formater ta chaine de recherche en fonction de ce que l'utilisateur a rentré!
Marsh Posté le 30-10-2007 à 17:30:16
Bon... là je crois qu'il est temps que je travaille un peu tout ça avant de revenir avec des bêtes questions !!!
(°-°)
Marsh Posté le 31-10-2007 à 13:47:01
Je crois que je vais en rester là pour le moment avec ma requete !
Je la ferai évoluer plus tard.
Des commentaires sur cetteversion de ma requete ?
SELECT p.nom, p.dimension, p.couleur_id, mc.type, COUNT(*) co
FROM mot_cle mc
INNER JOIN ph_fk_mcl ON mc.id = ph_fk_mcl.id_motcle
INNER JOIN photos p ON ph_fk_mcl.id_photo = p.id
WHERE (MATCH (mc.fr, mc.en) AGAINST ('homme* femme* enfant*' IN BOOLEAN MODE)) AND (p.couleur_id = '1')
GROUP BY p.nom, p.dimension, p.couleur_id, mc.type
ORDER BY co DESC
(°-°)
Marsh Posté le 31-10-2007 à 14:33:14
Heu, je vais peut-être dire une connerie, mais un DISTINCT, ce serait pas mieux qu'un GROUP BY ?
Là, on a pas besoin d'un regroupement ! Tout ce qu'on veut, c'est que les enregistrements soit distincts !
Marsh Posté le 31-10-2007 à 14:44:01
bah il fait un count() donc non, le group by n'est pas idiot
Marsh Posté le 31-10-2007 à 14:50:53
Ha mince ! J'avais zappé le fait qu'il voulait un tri par pertinence !
Donc effectivement, le GROUP BY n'est pas de trop !
Marsh Posté le 31-10-2007 à 19:41:02
Encore une petite question...
Est-ce que avec MySQL il y a moyen de rechercher des mots semblables phonétiquement, orthographiquement, ... ?
J'ai vu la distance levenstein en PHP mais je ne vois pas bien comment l'intégrer dans ma requete...
(°-°)
Marsh Posté le 31-10-2007 à 20:37:38
Extra ! On dirait bien que ça existe en MySQL !
Il y a aussi SOUNDS LIKE... Je vais voir tout ça...
Je pensais que ce n'était qu'une fonction PHP !
Merci à toi !!!
(°-°)
Marsh Posté le 26-10-2007 à 19:55:36
Bonjour !
J'ai fait un ou l'autre Post qui n'ont recueilli aucun succès... surement trop long, trop vague, trop...
J'ai donc travaillé un peu sur tout ça et voilà quelque chose de plus concis !
Voici une requete MySQL que j'ai sur une page. Elle est créée à partir d'une boucle en PHP se basant sur des mots cles entres par l'user.
SELECT p.nom, p.dimension, p.couleur_id, mc.type FROM mot_cle mc LEFT JOIN ph_fk_mcl ON mc.id = ph_fk_mcl.id_motcle LEFT JOIN photos p ON ph_fk_mcl.id_photo = p.id WHERE (mc.fr = 'amour' OR mc.en = 'amour' OR mc.fr = 'homme' OR mc.en = 'homme' OR mc.fr = 'femme' OR mc.en = 'femme') AND (p.couleur_id = '1');
Cette requete sélectionne des photos dans une table.
Le problème : si une photo est associee à 2 mots cles, elle est deux fois dans les résultats ! Or, je voudrais plutot que la pertinence de cette photo soit plus élevée que celle d'une photo associée à un seul mot cle !
Est-ce que je dois trier un peu le tout via un tableau PHP ?
Est-ce qu'il y a moyen de faire ça dans la requete ?
Merci d'avance !!