views:

640

answers:

1

I have developed a taxonomy for a site that I've been working on that may be abusing the categorization system of wordpress- posts are categorized both under what topics they refer to (let's say cats, dogs, monkeys) as well as what type of post it is (say, expert, organization, article). So I'd like to find all posts that are about cats and dogs and that are organizations. Something along the lines of IN (cats, dogs) AND IN (organizations)... at least how it makes sense to me, but I can't figure out the right SQL syntax for the task.

Based on what I found in this article on wordpress.com, I'm building from the query below... but I'm not sure of the right syntax for how to say 'I want something that belongs to (either category 1 or 2) and (belongs to category 3) (say, cat 1=cats, 2=dogs, 3=organizations).

This is probably really simple and i'll be kicking myself when I get the response.

SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->term_taxonomy.term_id = 1,2,3
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->posts.post_status = 'publish'
ORDER BY $wpdb->postmeta.meta_value ASC

Thanks!

+1  A: 

Since the two conditions exist on different rows of the term_taxonomy table, you have to join to that table twice in order to compare them in one row of the result set.

Also I don't think you need to use LEFT JOIN since you're using conditions in the WHERE clause. Outer joins usually perform slower than inner joins.

You can use table aliases so you don't have to keep repeating the variable table names.

So I haven't test this, but the following should be closer to what you need:

SELECT * FROM $wpdb->posts p
 INNER JOIN $wpdb->postmeta m ON (p.ID = m.post_id)
 INNER JOIN $wpdb->term_relationships r1 ON (p.ID = r1.object_id)
 INNER JOIN $wpdb->term_taxonomy x1
  ON (r1.term_taxonomy_id = x1.term_taxonomy_id)
 INNER JOIN $wpdb->term_relationships r2 ON (p.ID = r2.object_id)
 INNER JOIN $wpdb->term_taxonomy x2
  ON (r2.term_taxonomy_id = x2.term_taxonomy_id)
WHERE x1.term_id IN (1, 2) AND x1.taxonomy = 'category'
 AND x2.term_id = 3 AND x2.taxonomy = 'category'
 AND p.post_status = 'publish'
ORDER BY m.meta_value ASC
Bill Karwin
awesome; that worked like a charm. I added a 'GROUP BY p.id' so duplicate posts aren't returned. thanks!
bennettk