Requête bien costaud ...

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Requête bien costaud ...

par Hubert Roksor » 23 mars 2007, 12:42

C'est pour m'assurer que TAG1 n'est ni NULL ni vide.

par worm1 » 12 mars 2007, 04:15

Je vais pas créer un nouveau sujet , j'ai trouvé la solution ici ->
http://www.commentcamarche.net/faq/suje ... i-implicit

Sinon pour en revenir à ta requête , ca me sort bien les infos que j'ai besoin .

Juste par curiosité , ça signifie quoi ca :WHERE TAG1 > '' dans la requete?

Je te remercie :wink:

par Hubert Roksor » 12 mars 2007, 00:38

Il s'agit d'une erreur sans relation, liée à la configuration de ton client. Fais une recherche sur les forums et sur Google sur "Illegal mix of collations for operation ' IN '" et tu devrais trouver plus d'infos.

De mémoire, je crois qu'il faut déclarer le character set de ton client partout. Dans ton my.cnf dans toutes les sections, par exemple (moi j'utilise UTF-8, à toi d'adapter)

Code : Tout sélectionner

[client] default-character-set=utf8 [mysql] default-character-set=utf8 [mysqld] default-character-set=utf8
...et éventuellement le faire au début de la connexion à la base avec la requête

Code : Tout sélectionner

SET NAMES 'utf8'
Si tu as d'autres problèmes concernant ce message d'erreur, réponds dans le sujet correspondant ou crée un nouveau topic pour éviter de tout mélanger dans celui-là, merci ;)

par worm1 » 11 mars 2007, 23:17

Encore moi =)

J'ai essayé ta requete Hubert et ca m'a retourné cette erreur "Illegal mix of collations for operation ' IN '"

C'est à cause de ma version de mysql ? (4.1)

par worm1 » 10 mars 2007, 01:10

Merci beaucoup pour toutes vos reponses, il est un peu tard pour analyser tout ca ce soir ,je vais regarder vos solutions à tête reposée demain et je vous dirais comment j'ai avancé,en tout cas merci encore :wink:

Bonjour, j'ai pas eu le temps ce we de resoudre le truc, par contre pour les questions sur la table ,en fait j'ai un ID primary key auto incrementable dans ma table en fait c'est les caractéristiques d'un produit donc vous avez cette structure

ID | NOM | DESCRIPTION | TAG1 | TAG2 ETC.....

Donc ,je pense que ma conception n'est pas mauvaise dans ce genre de cas .

J'attaque la requête demain matin,je vous dirais si j'ai réussi :wink:

Re: Requête bien costaud ...

par Hubert Roksor » 09 mars 2007, 21:55

J'espere que c 'est clair, pour moi mon raisonnement sur papier l'est mais le retranscrire en sql c'est autre chose ^^
J'ai relu ton message, et si je comprends bien tu cherches à évaluer l'affinité entre les tags. Pour ce faire, tu récupères les identifiants des tous les articles taggés "musique" et tu établis un classement des autres tags.

Récupérer tous les articles taggés "musique"

Code : Tout sélectionner

SELECT article_id FROM table_normalisee WHERE tag = 'musique'
Récupérer le classement des tags

On réutilise la requête du précédent message, en ajoutant un WHERE pour la limiter aux articles dont on a précédemment récupéré les identificateurs. (pour ma table de test ce sont les articles 1,2,3,4,5,6 et 7)

Code : Tout sélectionner

SELECT COUNT(*) AS total, tag FROM table_normalisee WHERE article_id IN (1,2,3,4,5,6,7) AND tag <> 'musique' GROUP BY tag ORDER BY total DESC
Maintenant, si tu as beaucoup d'articles tu n'auras peut-être pas envie d'avoir une clause WHERE qui fait dix lignes, donc tu peux aussi chercher d'autres solutions basées sur une jointure. Donc je rappelle l'algorithme "pour chaque article associé au tag 'musique' compte le tags associé au même article et je groupe les résultat tag par tag". En SQL ça ce traduit par "je cherche dans la table 1 tous les articles taggés "musique", je joins la table 2 article par article et je compte les tags de la table 2 à condition que ce ne soit pas le même tag" (sinon le tag le plus souvent associé à "musique" serait... "musique")

Code : Tout sélectionner

SELECT COUNT(*) AS total, t2.tag FROM table_normalisee t1 JOIN table_normalisee t2 USING (article_id) WHERE t1.tag = 'musique' AND t2.tag <> t1.tag GROUP BY t2.tag ORDER BY total DESC
Si tu as tout suivi, cette requête remplace les deux premières. Et je sais que si tu crées un index PRIMARY sur les colonnes (article_id, tag) ainsi qu'un index simple sur (tag) elle est très performante. Évidemment, ce n'est valable que si tu normalises tes données.

En dernier, pour la postérité voici donnat le même résultat pour ta table pas normalisée. Attention, les performances sont astronomiquement mauvaises.

Code : Tout sélectionner

SELECT COUNT(*) AS total, tag FROM ( SELECT TAG1 AS tag FROM table_pas_normalisee WHERE TAG1 > '' AND 'musique' IN (TAG2, TAG3, TAG4, TAG5, TAG6) UNION ALL SELECT TAG2 AS tag FROM table_pas_normalisee WHERE TAG2 > '' AND 'musique' IN (TAG1, TAG3, TAG4, TAG5, TAG6) UNION ALL SELECT TAG3 AS tag FROM table_pas_normalisee WHERE TAG3 > '' AND 'musique' IN (TAG1, TAG2, TAG4, TAG5, TAG6) UNION ALL SELECT TAG4 AS tag FROM table_pas_normalisee WHERE TAG4 > '' AND 'musique' IN (TAG1, TAG2, TAG3, TAG5, TAG6) UNION ALL SELECT TAG5 AS tag FROM table_pas_normalisee WHERE TAG5 > '' AND 'musique' IN (TAG1, TAG2, TAG3, TAG4, TAG6) UNION ALL SELECT TAG6 AS tag FROM table_pas_normalisee WHERE TAG6 > '' AND 'musique' IN (TAG1, TAG2, TAG3, TAG4, TAG5) ) AS tmp GROUP BY tag ORDER BY total DESC
[Edit: en y réfléchissant il y a beaucoup de solutions différentes pour la table pas normalisée, mais ce n'est pas évident de trouver la plus performante. Si je devais faire une comparaison je dirais que c'est comme chercher le meilleur moyen de creuser un tunnel avec une petite cuillère. On ne le fait que lorsqu'on est vraiment vraiment obligé. Cette requête est la troisième itération et ne nécessite de lire la table entière "que" 6 fois d'affilée... la première version la lisait 12 fois d'affilée]

par Hubert Roksor » 09 mars 2007, 21:02

Petite démo rapide. Pour compter le nombre d'occurences d'un tag à partir d'une table normalisée et classer le résultat du plus fréquent au moins fréquent, la requête est

Code : Tout sélectionner

SELECT COUNT(*) AS total, tag FROM table_normalisee GROUP BY tag ORDER BY total DESC
L'embêtant c'est qu'on parle là d'une table normalisée. Pour te donner une idée de la complexité de la solution basée sur une table non normalisée on peut créer une vue (c'est comme une table virtuelle) de cette table hypothétique grâce à:

Code : Tout sélectionner

CREATE VIEW table_normalisee AS ( SELECT article_id, TAG1 AS tag FROM table_pas_normalisee WHERE TAG1 > '' UNION ALL SELECT article_id, TAG2 AS tag FROM table_pas_normalisee WHERE TAG2 > '' UNION ALL SELECT article_id, TAG3 AS tag FROM table_pas_normalisee WHERE TAG3 > '' UNION ALL SELECT article_id, TAG4 AS tag FROM table_pas_normalisee WHERE TAG4 > '' UNION ALL SELECT article_id, TAG5 AS tag FROM table_pas_normalisee WHERE TAG5 > '' UNION ALL SELECT article_id, TAG6 AS tag FROM table_pas_normalisee WHERE TAG6 > '' )
Pour résumer, cette "vue" c'est comme une table virtuelle qui ressemble à ce que devrais être ta vraie table. Tu peux t'en servir pour tester des requêtes SELECT mais tu ne pourra pas faire d'UPDATE ou INSERT dessus. De plus, ça ne fonctionne que sous MySQL 5.0. Et j'ai failli oublier de préciser que les performances peuvent être dramatiquement mauvaises. En clair, il va te falloir changer le format de ta table pour de bon.

PS: mince, j'avais mal survolé le premier post, je le relirai plus tard. Désolé si j'ai répondu à une autre question :P

par Hubert Roksor » 09 mars 2007, 20:42

Plus concrètement, au lieu d'avoir des données formatées sous la forme

Code : Tout sélectionner

1 musique radio blog playlist 2 musique messagerie radio téléchargement
il faut les organiser sous la forme

Code : Tout sélectionner

1 musique 1 radio 1 blog 1 playlist 2 musique 2 messagerie 2 radio 2 téléchargement
En faisant une recherche sur "normalisation" tu devrais trouver pas mal de topics similaires dans ce forum.
Là tu vas galérer. Je ne vois même pas comment faire personnellement.
Le truc que ne dit pas oukileou c'est que c'est un sujet qui revient toutes les semaines et qu'il en a marre de retaper la même chose :lol:

par ouckileou » 09 mars 2007, 20:25

Ce sont des colonnes de ta table ? Si tu as des colonnes qui se répètent, c'est qu'il y un problèmede conception (col1, col2, col3)

Tu aurais une table extérieure "tags", avec un id_article (ou je ne sais pas ce que c'est) et un libelle_tag, ce serait très simple à compter.

Là tu vas galérer. Je ne vois même pas comment faire personnellement.

Requête bien costaud ...

par worm1 » 09 mars 2007, 20:21

Bonjour 8-)

Voilà j'ai une requête assez complexe qui dépasse mes compétences ...

Je dois ressortir la fréquence des tags associés à un tag donné . Pour être clair voici le tableau qui doit me permettre de ressortir ces frequences:

Image

Donc je sors ca avec le tag "musique"

Maintenant il me faudrait la requete qui me sorte les differents tags exceptes musique avec le nombre de leur frequence.Avec l'exemple ca devrait donner

mp3 / 2
téléchargement / 4
messagerie / 1
etc....

J'espere que c 'est clair, pour moi mon raisonnement sur papier l'est mais le retranscrire en sql c'est autre chose ^^ Merci pour aide :wink: