MySQL Join Same Table
Make an outer (left) join to itself, filtering on those records that don't match by looking for rows with a null id in the joined table:
select t1.*
from meta_data t1
left join meta_data t2 on t2.post_id = t1.post_id and t2.meta_key='def'
where t1.meta_key='abc'
and t2.id is null
To achieve this you should use the LEFT OUTER JOIN operation joining the same table.
SELECT a.*
FROM meta_data a
LEFT OUTER JOIN meta_data b ON a.post_id = b.post_id AND b.meta_value = 'def'
WHERE
a.meta_value = 'abc'
AND b.post_id IS null