Filter results by lack of a value

I am trying to run a query to update the value of a custom field in a WordPress wp_postmeta table. The data looks like this:

meta_id     post_id     meta_key          meta_value
-------     -------     -------           ----------
1           1           start_date        2011-12-30
2           1           start_time        21:00
3           363         start_date        2011-12-29
4           363         start_time        21:00
5           363         _start_timestamp  2011-12-29 21:00

I would like to make a query to add a record with a meta_key value of _start_timestamp that combines the values of start_date and start_time for a given post_id, but only in the cases where the _start_timestamp was not already set.

Read More

Before going into the INSERT query, I tried to get a SELECT query that would show the stuff I wanted. I managed to make a SELECT query that returns the post IDs that HAVE the _start_timestamp defined, but can’t figure out how to get the ones that do not have it defined.

This is what I have:

SELECT 
a.post_id, 
CONCAT(a.meta_value, ' ', b.meta_value), 
c.meta_value
FROM 
wp_postmeta a
INNER JOIN wp_postmeta b ON a.post_id=b.post_id
INNER JOIN wp_postmeta c ON a.post_id=c.post_id
WHERE 
a.meta_key = 'start_date' 
AND b.meta_key = 'start_time' 
AND c.meta_key='_start_eventtimestamp'

This returns

post_id     CONCAT(a.meta_value, ' ', b.meta_value)     meta_value
363         2011-12-29 21:00                                2011-12-29 21:00

How can I specify to get the results only when _start_timestamp is not present in the meta_key column for a given post_id? In this case, it should return only the post_id 1.

Related posts

Leave a Reply

1 comment

  1. Try:

    SELECT 
    a.post_id, 
    CONCAT(a.meta_value, ' ', b.meta_value), 
    c.meta_value
    FROM 
    wp_postmeta a
    INNER JOIN wp_postmeta b ON a.post_id=b.post_id
    LEFT JOIN wp_postmeta c ON a.post_id=c.post_id AND 
                               c.meta_key='_start_eventtimestamp'
    WHERE 
    a.meta_key = 'start_date' 
    AND b.meta_key = 'start_time' 
    AND c.post_id is null
    

    EDIT: An alternative approach:

    SELECT post_id,
           '_start_timestamp' as meta_key,
           concat(max(case meta_key when 'start_date' then meta_value end), ' ',
                  max(case meta_key when 'start_time' then meta_value end) 
                 ) as meta_value
    from wp_postmeta
    group by post_id
    having max(case meta_key when 'start_date' then meta_value end) is not null and
           max(case meta_key when 'start_time' then meta_value end) is not null and
           max(case meta_key when '_start_timestamp' then meta_value end) is null