Comment faire ?

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 : Comment faire ?

par Truc » 17 oct. 2006, 22:01

Qu'est ce qu'il veut le monsieur ?! :-s :lol:
Ben, j'sais pas. Ça doit être indiqué dans le titre de son sujet... :-*

Quand je pense qu'on en a dé-viPHP-isés pour moins que ça... :axe: :lol:
:-({|= :boire4: :boire9:

Non mais je parlais surtout de l'intervention juste avant ce message de "no comprehension" :roll:


Honnêtement ma requête ne sort pas le résultat attendu ?

Dire que je l'ai testé... et re-testé (bien sûr il n'y avait pas les clauses sur les "etat" et "niveau" puisqu'il n'en était pas question à ce moment... quoi je ne cherche pas à me disculper :^o )

par albat » 17 oct. 2006, 17:56

Qu'est ce qu'il veut le monsieur ?! :-s :lol:
Ben, j'sais pas. Ça doit être indiqué dans le titre de son sujet... :-*

Quand je pense qu'on en a dé-viPHP-isés pour moins que ça... :axe: :lol:

par Hubert Roksor » 17 oct. 2006, 17:29

Je dirais que ceci fait office de jointure
Euh... non :P
MySQL ne lit pas dans les pensées, et si une jointure n'est pas explicite alors il joint tous les enregistrements de la première table à tous les enregistrements de la seconde. S'il y a 100 enregistrements dans la première et 200 dans la seconde ça fait 20000 combinaisons :lol:

Après avoir (re)lu le premier message, je pense qu'il doit y avoir un champs "id_admin" quelque part pour faire la jointure. Auquel cas, mon exemple de table dérivée serait

Code : Tout sélectionner

SELECT t.*, m.id, m.message FROM administrateurs AS a JOIN tickets AS t ON t.id_admin = a.id JOIN ( SELECT id_ticket, MAX(id) AS max_id FROM messages GROUP BY id_ticket ) AS tmp ON tmp.id_ticket = t.id JOIN messages AS m ON m.id_ticket = tmp.max_id WHERE a.etat = 1 AND t.etat = 1
Et la table dérivée pourrait être améliorée parce qu'elle représente le "max_id" de tous les tickets, alors que seuls les tickets dont l'"etat" est à 1 seront utilisés. Même si ça nous fait ajouter jointures dans la table dérivée ça peut être plus performant parce qu'il aura à examiner moins d'enregistrements. Mais bon, dans tous les cas => champs supplémentaire, c'est une meilleure solution.

par Vikchill » 17 oct. 2006, 17:21

Je dirais que ceci fait office de jointure:

Code : Tout sélectionner

AND a.etat='1' AND t.etat='1'
ça équivaut à

Code : Tout sélectionner

AND a.etat=t.etat AND t.etat='1'
Pour le reste on est d'accord, cette solution est beaucoup plus lourde en ressources machine.

par Hubert Roksor » 17 oct. 2006, 17:15

Ca fonctionne, ca me permet d'enlever de champ ajouté pour contourner le prob
Il y a une raison pour que les développeurs aient ajouté un champs "topic_last_post_id", c'est qu'il est très coûteux de calculer ce champs à la volée.

Attention aux sous-requêtes corrélées (correlated subqueries) elles sont très très coûteuses en terme de ressources, et d'autant plus que tu voudras probablement utiliser le résultat de cette requête pour la clause ORDER BY afin de classer les sujets par ordre de nouveauté, ce qui ôte toute chance à l'optimiseur de réécrire la requête. Au pire, si vous ne pouvez faire autrement qu'utiliser une requête corrélée, vous pouvez la transformer en table dérivée mais là encore c'est très lent parce que le MAX() sera calculé sur l'intégralité de la table.

Dans tous les cas, je ne saurai trop te conseiller de garder ce champ supplémentaire quelles que soient les circonstances.

Au fait, j'ai essayé de réécrire la requête ci-dessous pour donner un exemple de table dérivée mais je n'y suis pas arrivé parce que je n'ai pas trouvé la relation entre la table "a" et la table "t", je pense qu'il manque une condition de jointure non ?

par Vikchill » 17 oct. 2006, 11:17

Y a vraiment pas de quoi. Je t'avoue être soulagé, j'ai vraiment du mal à travailler dans l'abstrait, la prochaine fois file-moi des tables, pour l'amour du ciel :p

par DocType » 17 oct. 2006, 11:14

Nickel !!!!!!!!!!!!!!!!!!!!!!!!!!!!
Ca fonctionne, ca me permet d'enlever de champ ajouté pour contourner le prob ^^

Merci @ toi et à ceux qui se sont penchés sur le problème :wink:

par Vikchill » 17 oct. 2006, 10:55

Non, toujous pas... la requête bien mais seulement ceux où l'id de ticket ) l'id du message.
Alors là il y a une forte odeur de boulettisation de ma part... je crois que je me suis embrouillé dans les alias de la requête imbriquée:

Code : Tout sélectionner

SELECT t.*, m.id, m.message FROM administrateurs As a, tickets As t, messages As m WHERE a.niveau='1' AND a.etat='1' AND t.etat='1' AND t.id=m.id_ticket AND m.id= (SELECT MAX(n.id) FROM messages n WHERE n.id_ticket=t.id) GROUP BY t.id
En espérant que ça fonctionne :s Bon, tu as une solution de secours, mais j'aurais aimé qu'on trouve la réponse. Mon problème c'est que j'ai du mal à trouver la solution sans pouvoir manipuler les données :(

par DocType » 17 oct. 2006, 10:45

Non, toujous pas... la requête bien mais seulement ceux où l'id de ticket ) l'id du message.
J'ai quand même trouvé la solution au problème en grattant à la porte de phpbb ! J'ajoute dans ma table tickets (les sujets) une variable que je vais updater au fur et à mesure. Celle ci s'appelle last_post_id qui comme la traduction française le signale, contient l'identifiant du derneire message qui lui est associé.

Toutefois si quelqu'un trouve la solution sans cette variable, je suis à l'écoute ;-)

par Vikchill » 17 oct. 2006, 10:34

Code : Tout sélectionner

SELECT t.*,m.id,m.message FROM administrateurs As a, tickets As t, messages As m WHERE a.niveau='1' AND a.etat='1' AND t.etat='1' AND t.id=m.id_ticket AND m.id= (SELECT MAX(m.id) FROM messages As m, tickets As t WHERE t.id=m.id_ticket GROUP By m.id)
Idem, ça me renvoi plusieurs champs donc bai*é...
Oui, forcément ça peut marcher de cette façon. Tu peux filer un petit jeu d'essai que je tente ma chance dans ma base MySQL de test?

A l'aveugle et instinctivement:

Code : Tout sélectionner

SELECT t.*, m.id, m.message FROM administrateurs As a, tickets As t, messages As m WHERE a.niveau='1' AND a.etat='1' AND t.etat='1' AND t.id=m.id_ticket AND m.id= (SELECT MAX(m.id) FROM messages n WHERE n.id=t.id) GROUP BY t.id
Je sais que ça a l'air tordu...

par DocType » 17 oct. 2006, 10:16

Code : Tout sélectionner

SELECT t.*,m.id,m.message FROM administrateurs As a, tickets As t, messages As m WHERE a.niveau='1' AND a.etat='1' AND t.etat='1' AND t.id=m.id_ticket AND m.id= (SELECT MAX(m.id) FROM messages As m, tickets As t WHERE t.id=m.id_ticket GROUP By m.id)
Idem, ça me renvoi plusieurs champs donc bai*é...
Pour ceux qui m'aideraient à résoudre mon problème, c'est une reqête qui permet de "sélectionner le dernier message de chaque ticket" où tickets et la table de tickets et messages la table de messages...

par Vikchill » 17 oct. 2006, 10:09

Tu peux pas faire de where sur le max(id), mais tu peux faire un WHERE id = (SELECT MAX(id) ... ), je sais pas si ça te servira.

par DocType » 17 oct. 2006, 09:42

Youpla boum
ma requête :

Code : Tout sélectionner

SELECT t . * , MAX( m.id ) , m.message FROM administrateurs AS a, tickets AS t, messages AS m WHERE a.niveau = '1' AND a.etat = '1' AND t.etat = '1' AND t.id = m.id_ticket GROUP BY t.id LIMIT 0 , 30
Problème : Les m.message ne correspondent pas au m.id ...

Illustration :
Image

Que faire dans ma requête ? je peux tout de même pas faire une clause where sur un max(id ) ???
J'ai pensé à une requête imbriquée, zen pensez quoi ?
[ EDIT ] requête imbriquée pas possible car elle renverrait plus d'un champ...

par DocType » 16 oct. 2006, 15:58

ba justement, je fais cette requete, mais ca me rapporte tout sauf le texte de mon max(id)... je suis en GROUP By etc...
bizarre :?

Jvous tiens au courant mes z'amours ^^

par Ryle » 16 oct. 2006, 15:39

Pour le group by, ce sont les champs qui sont groupés qu'il faut utiliser ;)
SELECT MAX( id_sujet ), sujet, texte FROM message GROUP BY sujet, texte

Ceci dit, tu peux également faire un simple "SELECT ...", un "ORDER BY id DESC" pour avoir le dernier en tête et un "LIMIT 0, 1" pour ne ramener que celui là :)