I have a blog that I need to re-order based on the number of values in a completely custom table. The reason I am not using meta data is a bit complex, but this is just what I need to do.
I just need to count the number of rows in the table wp_upvotes
which have a postID
that matches the ID
of the WordPress blog post, and order it by most “upvotes” to least. This result should include the WordPress post even if there are no values in the wp_upvotes
table.
The query I am trying is this:
$post = $wpdb->get_results("
SELECT wp_posts.*, COUNT(wp_upvotes.id) AS upvotes
FROM wp_posts
LEFT JOIN wp_upvotes
ON wp_posts.ID = wp_upvotes.postID
WHERE wp_posts.post_status = 'publish'
AND wp_posts.post_type = 'post'
ORDER BY upvotes DESC, wp_posts.date DESC
LIMIT $pageNum, $numToLoad
", ARRAY_A);
If you want to ensure that there is a match between each table, you are correct to use a
LEFT JOIN
– an easy way to think about it is that everything on the “left” (wp_posts
) will be included, and things on the “right” (wp_upvotes
) will be included if they have a match, otherwise null. Just usingJOIN
will ensure that rows from both tables will only be shown if there is a match.My guess is that you need to include a
GROUP BY p.ID
to have eachupvotes
value specific to a particular post.As a note, you also have an error using
wp_posts.date
instead ofwp_posts.post_date
;It’s also a good idea to use the
$wpdb-posts
and$wpdb-prefix
properties in case you want to use this somewhere with a database prefix that is notwp_
.If you just want to see the results of the data in
wp_posts
you can just run a database query with anORDER BY
and return the columns, or if you want to use the WordPress filters (on things likethe_title()
andthe_content()
you can pass the post IDs into a WP_Query with thepost_id__in
andorderby=post__in
arguments – you would need to reference back the$upvotes
value by ID however.