mootymoots
mootymoots

Reputation: 4575

MySQL query condition on joined tables

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

Answers (1)

Bilal Akil
Bilal Akil

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

Related Questions