Requète avec OR -> résultats farfelus

Manille
Invité n'ayant pas de compte PHPfrance

29 mai 2008, 14:57

Hello


j'essaye de faire une requète avec une jointure et plusieurs conditions visant à sélectionner des articles correspondant à ma demande afin de les afficher sur ma page ensuite. La requète suivante marche parfaitement :

Code : Tout sélectionner

$sql = "SELECT wp_posts.post_title, DATE_FORMAT(wp_posts.post_date, '%d-%m-%Y') as datefr, wp_posts.post_date, wp_posts.post_name, wp_posts.id, wp_term_relationships.object_id, wp_term_relationships.term_taxonomy_id FROM wp_posts, wp_term_relationships WHERE wp_term_relationships.term_taxonomy_id=27 AND wp_posts.id=wp_term_relationships.object_id ORDER BY wp_posts.post_date DESC LIMIT 10";

Seulement je voudrais rajouter également les articles dont term_taxonomy_id=31. Je rajoute donc simplement cette condition dans ma requète avec un OR ce qui donne la requète suivante :

Code : Tout sélectionner

$sql = "SELECT wp_posts.post_title, DATE_FORMAT(wp_posts.post_date, '%d-%m-%Y') as datefr, wp_posts.post_date, wp_posts.post_name, wp_posts.id, wp_term_relationships.object_id, wp_term_relationships.term_taxonomy_id FROM wp_posts, wp_term_relationships WHERE wp_term_relationships.term_taxonomy_id=27 OR wp_term_relationships.term_taxonomy_id=31 AND wp_posts.id=wp_term_relationships.object_id ORDER BY wp_posts.post_date DESC LIMIT 10";

Et là ca ne marche plus ! Lorsque je fais un print_r sur la tableau il me renvoie 568 enregistrements (au lieu de 11 normalement) et avec de nombreux doublons voire 5 fois le même article (qui en plus n'a rien à voir).

Pourtant mon OR xxx semble bien placé, je comprends pas d'ou ca vient.



P.S : j'ai essayé de remplacer wp_term_relationships.term_taxonomy_id=27 OR wp_term_relationships.term_taxonomy_id=31 par wp_term_relationships.term_taxonomy_id IN (27,31) : là ca fontionne bien sauf qu'il me sélectionne plusieurs fois certains articles vu qu'ils contiennent à la fois 27 et 31. C'est donc bien une requète avec OR qu'il me faut mais je n'arrive pas à obtenir des résultats cohérents.

Vous voyiez d'ou ca vient (problème de syntaxe, de disposition...) ?


P.S 2 : je sais pas comment on fait CREATE TABLE pour le schéma des tables

Eléphant du PHP | 396 Messages

29 mai 2008, 15:11

Je n'ai pas tout regardé (et de tout façon sans la structure de tes tables c'est difficile de deviner quoique ce soit ;) ) mais je pense qu'il faut que, déjà, tu fasses :

Code : Tout sélectionner

WHERE (cond1 OR cond2) AND

Manille
Invité n'ayant pas de compte PHPfrance

29 mai 2008, 15:15

Je crois que j'avais déjà tenté mais je vais essayer !

Pour la structure des tables je sais pas comment faire pour copier ca là. Cependant ca ne change pas grand chose au pb étant donné que ma première requète fonctionne parfaitement. C'est juste quand je rajoute le OR xxx que le problème apparait donc ca vient pas des tables mais de la "syntaxe" de ma requète.

Je vais tenter avec les parenthèses ! :)

Manille
Invité n'ayant pas de compte PHPfrance

29 mai 2008, 15:33

Je viens d'essayer, ca marche déjà nettement mieux : il me sélectionne les bons articles et seulement 11 comme prévu. Je sais pas si c'est normal mais lorsque je fais

Code : Tout sélectionner

wp_term_relationships.term_taxonomy_id=27 OR wp_term_relationships.term_taxonomy_id=31
ca me donne le même résultat que

Code : Tout sélectionner

wp_term_relationships.term_taxonomy_id IN (27,31)

Quoi qu'il en soit c'est tout proche de ce que je cherche à faire seulement c'est pas encore tout à fait ca. En effet là il me sélectionne à chaque fois les articles dont term_taxonomy_id= 27 ou term_taxonomy_id=31. Mais comme certains articles ont parfois term_taxonomy_id=27 ET term_taxonomy_id=31 il me les affiche deux fois...

Ce que je voudrais c'est qu'il ne me sélectionne qu'une seule fois les articles qui correspondent à l'une ou l'autre des conditions. Et pas à chaque fois qu'une des conditions est respectée.

Je sais pas si je suis clair... :)

Manille
Invité n'ayant pas de compte PHPfrance

29 mai 2008, 15:35

Dans mon message précédent la requète avec OR est bien sûr entre parenthèses ! J'ai oublié de les metrte dans le code, pardon.

Eléphant du PHP | 175 Messages

29 mai 2008, 15:46

pour l'unicité GROUP BY est ton amie

Code : Tout sélectionner

(wp_term_relationships.term_taxonomy_id=27 OR wp_term_relationships.term_taxonomy_id=31) wp_term_relationships.term_taxonomy_id IN (27,31)
C'est en effet la meme chose, la deuxieme est utilisée en cas de nombreuses valeur par exemple.

Manille
Invité n'ayant pas de compte PHPfrance

29 mai 2008, 16:07

Exactement ce qu'il me fallait ! Image

C'est bon de connaitre le manuel comme il faut... :)

J'en apprends un peu plus chaque jour, merci à vous deux pour votre aide !

Mammouth du PHP | 2937 Messages

29 mai 2008, 16:47

De plus, il ne faut pas oublier la précédence des opérateurs (autrement dit, l'échelle de priorité entre les différents opérateurs), sachant qu'en l'absence de parenthèses, l'opérateur AND est prioritaire par rapport à l'opérateur OR (de même qu'en mathématiques, les mutiplications et divisions sont prioritaires par rapport aux additions et soustractions dans un calcul sans parenthèses ni crochets).

Par conséquent, la requête suivante

Code : Tout sélectionner

SELECT colonne FROM table WHERE cond1 OR cond2 AND cond3
revient à dire

Code : Tout sélectionner

SELECT colonne FROM table WHERE cond1 OR (cond2 AND cond3)

Eléphant du PHP | 422 Messages

29 mai 2008, 16:56

Et s'il te renvoie des articles en double

Code : Tout sélectionner

select distinct colonne1, colonne2, ...
Conseil juste pour que ce soit un peu plus lisible, surtout quand tu as de grands noms : utilises des alias et des retour-chariots
$sql = "SELECT p.post_title, DATE_FORMAT(p.post_date, '%d-%m-%Y') as datefr, p.post_date, p.post_name, p.id,
      t.object_id, t.term_taxonomy_id 
      FROM wp_posts p, wp_term_relationships t
      WHERE t.term_taxonomy_id=27 
      AND p.id=t.object_id
      ORDER BY p.post_date DESC 
      LIMIT 10";