I’m trying to query two WordPress tables, ie. posts
and postmeta
.
Basically the tables and rows I’m interested looks like this:
| ---- ** posts ** ---- | | -------- ** postmeta ** ---------- |
| ID | post_type | | post_id | meta_key | meta_value |
|-----------------------| |------------------------------------|
| 1 | player | | 1 | number | 10 |
| 2 | player | | 2 | number | 20 |
| 3 | player | | 3 | othre_key | aaa |
| 4 | other_type | | 4 | other_key | xxx |
| 4 | other_type | | 5 | other_key | yyy |
| 4 | other_type | | 6 | other_key | zzz |
I want to get all posts where post_type = player
and order them by postmeta.meta_value
where the postmeta.meta_key = number
whether or not the postmeta
row exists.
so far I’ve got this:
SELECT a.ID, a.post_title, b.meta_value, b.meta_key
FROM $wpdb->posts AS a
INNER JOIN $wpdb->postmeta AS b
ON a.ID = b.post_id
AND b.meta_key = %s
WHERE a.post_status = %s
AND a.post_type = %s
GROUP BY a.ID
ORDER BY b.meta_value+(0) ASC, a.post_title ASC
…which returns the players that has a number postmeta associated with them.
How do I append the players that doesn’t have that postmeta to the result within same query so that the desired result would look something like this?
| --- ** result ** ---- |
| ID | meta_value |
|-----------------------|
| 1 | 10 |
| 2 | 20 |
| 3 | null |
Use
LEFT JOIN
instead ofINNER JOIN
:As you can see in this great explanation of JOINS,
LEFT JOIN
returns all the results from the LEFT table and adds the information that is in the RIGHT table, whenever the JOIN condition is matched.As for
INNER JOIN
, only returns results that match the join conditionAs Filipe said, you want to use LEFT JOIN.
The left join is for the most part the same as a inner join. It puts together all matching records, according to the on specification.
The difference is that all records from the LEFT Table, (the table you wrote before the join operator), will also be returned in the query results.
All values from the right table fields will be set to NULL.
Further more, to get only rows from the left table that doesn’t match the right table, you could add a where b.post_id IS NULL.