This is a very specific question regarding MySQL as implemented in WordPress.
I’m trying to develop a plugin that will show (select) posts that have specific ‘tags‘ and belong to specific ‘categories‘ (both multiple)
I was told it’s impossible because of the way categories and tags are stored:
wp_posts
contains a list of posts, each post have an “ID”wp_terms
contains a list of terms (both categories and tags). Each term has a TERM_IDwp_term_taxonomy
has a list of terms with their TERM_IDs and has a Taxonomy definition for each one of those (either a Category or a Tag)wp_term_relationships
has associations between terms and posts
How can I join the tables to get all posts with tags “Nuclear” and “Deals” that also belong to the category “Category1”?
I misunderstood you. I thought you wanted Nuclear or Deals. The below should give you only Nuclear and Deals.
Try this:
Essentially I’m employing 2 copies of the pertinent child tables – terms, term_taxonomy, and term_relationship. One copy applies the ‘Category1’ restriction, the other the ‘Nuclear’ or ‘Deals’ restriction.
BTW, what kind of project is this with posts all about nuclear deals? You trying to get us on some government list? 😉
What a gross DB structure.
Anyway, I’d do something like this (note I prefer EXISTS to joins, but you can re-write them as joins if you like; most query analyzers will collapse them to the same query plan anyway). You may have to do some additional juggling one way or another to make it work…
So I tried both options on my WordPress db. I looked for the category “Tech” in my posts with the tags “Perl” AND “Programming”.
Eric’s worked once I added a missing comma in the initial select statement. It returned 3 records. The problem is that the section that is looking for the “post_tag” is actually working as an OR option. One of my posts only had one tag not both. Also it would be good to make the SELECT DISTINCT.
I tried Matt’s version, but it kept returning an empty set. I may try to “juggle” with it.
Thanks @Eric it works! Just a few code corrections for future reference:
should be
Really so great answer .. helped me a lot..
great bcoz., it gave me basic approach to build my complex query !
one small correction, for ready users like me 🙂
“wp_term_relationship” will give ‘doesn’t exist error’
.. use wp_term_relationships as it is the correct table name.
Thanks Eric