WP_Query produces wrong SQL
-
The issue is that WP_Query seems to mix up some things, let me show you.
It’s the meta_query that gets messed up in the SQL.
This is the WP_Query arguments and as you can see I order on “list_prio” and “meta_value_num”:
Array ( [post_type] => Array ( [0] => post [1] => page ) [post_status] => Array ( [0] => publish [1] => draft ) [posts_per_page] => [cat] => [meta_key] => _item_rating_value_key [meta_query] => Array ( [relation] => OR [list_prio] => Array ( [key] => _affiliate_list_73_prio_value_key [type] => NUMERIC [compare] => EXISTS ) [list_no_prio] => Array ( [key] => _affiliate_list_73_prio_value_key [compare] => NOT EXISTS ) ) [orderby] => Array ( [list_prio] => DESC [meta_value_num] => DESC ) [tax_query] => Array ( [0] => Array ( [taxonomy] => list [field] => term_id [terms] => 73 ) ) )
The SQL produced by this looks like below and there are 2 errors here.
1. The “ORDER BY” uses mt1 as order since that is the one in the meta_query BUT if you look in te LEFT JOIN for mt1 it is missing the
AND mt1.meta_key = '_affiliate_list_73_prio_value_key'
which makes the SQL query just get a random meta_key from the db instead and order on that.2. In the LEFT JOIN with mt2 I do have the correct meta_key, but why in mt2, that should be the group with no meta_key named like that. So what if I [orderby] on “list_no_prio” instead? Well scroll past this code block.
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID, wp_posts.post_title, mt2.meta_key, CAST(mt2.meta_value AS SIGNED), wp_casinohawks_postmeta.meta_key, CAST(wp_casinohawks_postmeta.meta_value AS SIGNED) FROM wp_posts LEFT JOIN wp_casinohawks_term_relationships ON ( wp_posts.ID = wp_casinohawks_term_relationships.object_id ) LEFT JOIN wp_casinohawks_postmeta ON ( wp_posts.ID = wp_casinohawks_postmeta.post_id ) LEFT JOIN wp_casinohawks_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) LEFT JOIN wp_casinohawks_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id AND mt2.meta_key = '_affiliate_list_73_prio_value_key' ) WHERE 1 = 1 AND ( wp_casinohawks_term_relationships.term_taxonomy_id IN (73) ) AND ( wp_casinohawks_postmeta.meta_key = '_item_rating_value_key' AND ( mt1.meta_key = '_affiliate_list_73_prio_value_key' OR mt2.post_id IS NULL ) ) AND wp_posts.post_type IN ('post', 'page') AND ( ( wp_posts.post_status = 'publish' OR wp_posts.post_status = 'draft' ) ) GROUP BY wp_posts.ID ORDER BY CAST(mt1.meta_value AS SIGNED) DESC, wp_casinohawks_postmeta.meta_value + 0 DESC LIMIT 0, 10
Ok so here I changed the WP_Query to sort on “list_no_prio” instead, which is the group of posts that don’t have the meta_key I want to sort on. And now it works, it’s like WP_Query mixes up the SQL right? Here you can see that in the query the correct meta_key is in mt1 but in the LEFT JOIN it is in mt2.
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts LEFT JOIN wp_casinohawks_term_relationships ON ( wp_posts.ID = wp_casinohawks_term_relationships.object_id ) LEFT JOIN wp_casinohawks_postmeta ON ( wp_posts.ID = wp_casinohawks_postmeta.post_id ) LEFT JOIN wp_casinohawks_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) LEFT JOIN wp_casinohawks_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id AND mt2.meta_key = '_affiliate_list_73_prio_value_key' ) WHERE 1 = 1 AND ( wp_casinohawks_term_relationships.term_taxonomy_id IN (73) ) AND ( wp_casinohawks_postmeta.meta_key = '_item_rating_value_key' AND ( mt1.meta_key = '_affiliate_list_73_prio_value_key' OR mt2.post_id IS NULL ) ) AND wp_posts.post_type IN ('post', 'page') AND ( ( wp_posts.post_status = 'publish' OR wp_posts.post_status = 'draft' ) ) GROUP BY wp_posts.ID ORDER BY CAST(mt2.meta_value AS CHAR) DESC, wp_casinohawks_postmeta.meta_value + 0 DESC LIMIT 0, 10
Any suggestions or if you see something wrong let me know. Thanks in advance, this has been a week long issue.
- The topic ‘WP_Query produces wrong SQL’ is closed to new replies.