Reputation: 4575
I have the following MySQL Query (querying wordpress db):
SELECT wp_posts.ID, wp_posts.post_date, wp_posts.post_content, wp_posts.post_title, wp_terms.name, wp_term_taxonomy.taxonomy
FROM wp_posts
LEFT JOIN wp_term_relationships ON ( wp_term_relationships.object_id = wp_posts.ID )
LEFT JOIN wp_term_taxonomy ON ( wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id )
LEFT JOIN wp_terms ON ( wp_terms.term_id = wp_term_taxonomy.term_id)
WHERE 1=1
AND wp_terms.name != 'MyTagName'
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish')
ORDER BY wp_posts.post_date DESC
LIMIT 100
I am basically trying to STOP all 'wp_posts' coming back that have a tag (db table wp_terms) 'MyTagName'. But all the above seems to do is strip that tag name out from the rows returned, leaving the wp_post entry in there with the other tag entries it is tagged with.
Can anyone help me with this?
Upvotes: 0
Views: 940
Reputation: 4755
SELECT wp_posts.ID, wp_posts.post_date, wp_posts.post_content, wp_posts.post_title, wp_terms.name, wp_term_taxonomy.taxonomy
FROM wp_posts
JOIN wp_term_relationships ON wp_term_relationships.object_id = wp_posts.ID
JOIN wp_term_taxonomy ON wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id
JOIN wp_terms ON wp_terms.term_id = wp_term_taxonomy.term_id
WHERE NOT EXISTS (
SELECT 1
FROM wp_term_relationships
JOIN wp_term_taxonomy ON wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id
JOIN wp_terms ON wp_terms.term_id = wp_term_taxonomy.term_id
WHERE wp_term_relationships.object_id = wp_posts.ID
AND wp_terms.name = 'MyTagName'
)
AND wp_posts.post_type = 'post'
AND wp_posts.post_status = 'publish'
ORDER BY wp_posts.post_date DESC
LIMIT 100
The problem is that your current solution isn't checking all wp_terms that relate to the post, just the specific one. If there were 5 terms, one of which was 'MyTagName', then that single one would be discluded but the other 4 will still be joined.
Now regarding the:
AND wp_posts.post_type = 'post'
AND wp_posts.post_status = 'publish'
You don't need to put them in the big NOT EXISTS check because that post won't be picked up anyway if either of them are false.
Upvotes: 1