• Hi,

    I recently ran into a problem that I even went as far as installing a fresh install of WordPress with no plugins activated and could recreate the exakt same problem. So here’s my situation:

    I have a post type called “html5-blank”. It has two meta boxes attached to it, “field1” and “field2”. I want to do a WP_Query that acts like a search in that it does a “LIKE” comparisation against those fields. I then want to sort the results on the meta fields, which I read was perfectably possible here: https://make.ww.wp.xz.cn/core/2015/03/30/query-improvements-in-wp-4-2-orderby-and-meta_query/

    But I soon discovered there was a limitation to this – the relation field in the meta query had to be set to “AND” and not to “OR”. So consider this args array, sent into a WP_Query:

    $args = array(
    	'post_type' => array('html5-blank'),
    	'posts_per_page' => '-1',
    	'meta_query' => array(
    		'relation' => 'AND',
    		'field1' => array(
    			'key'     => 'field1',
    			'value'   => 'test',
    			'compare' => 'LIKE'
    		),
    		'field2' => array(
    			'key'     => 'field2',
    			'value'   => 'test',
    			'compare' => 'LIKE'
    		),
    	),
    
    	'orderby' => array(
    		'field1' => 'ASC',
    		'field2' => 'ASC',
    		'title' => 'ASC',
    	)
    );

    This results in this query:

    SELECT wp_posts.* FROM wp_posts INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) WHERE 1=1 AND ( ( wp_postmeta.meta_key = 'field1' AND wp_postmeta.meta_value LIKE '%test%' ) AND ( mt1.meta_key = 'field2' AND mt1.meta_value LIKE '%test%' ) ) AND wp_posts.post_type = 'html5-blank' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value ASC, CAST(mt1.meta_value AS CHAR) ASC, wp_posts.post_title ASC test

    This seems fine to me. But then consider this, it’s the exact same WP_Query arguments but with the relation set to “OR”:

    $args = array(
    	'post_type' => array('html5-blank'),
    	'posts_per_page' => '-1',
    	'meta_query' => array(
    		'relation' => 'OR',
    		'field1' => array(
    			'key'     => 'field1',
    			'value'   => 'test',
    			'compare' => 'LIKE'
    		),
    		'field2' => array(
    			'key'     => 'field2',
    			'value'   => 'test',
    			'compare' => 'LIKE'
    		),
    	),
    
    	'orderby' => array(
    		'field1' => 'ASC',
    		'field2' => 'ASC',
    		'title' => 'ASC',
    	)
    );

    Which results in this SQL query:

    SELECT wp_posts.* FROM wp_posts INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) WHERE 1=1 AND ( ( wp_postmeta.meta_key = 'field1' AND wp_postmeta.meta_value LIKE '%test%' ) OR ( wp_postmeta.meta_key = 'field2' AND wp_postmeta.meta_value LIKE '%test%' ) ) AND wp_posts.post_type = 'html5-blank' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value ASC, CAST(wp_postmeta.meta_value AS CHAR) ASC, wp_posts.post_title ASC test

    Here, the orderby fall completely apart. So I’m wondering if this is by design or some kind of bug?

    I created this account here just caused I didn’t know where to put this. If this is the wrong forum, then feel free to point me in the right direction. 🙂

Viewing 2 replies - 1 through 2 (of 2 total)
  • Moderator bcworkz

    (@bcworkz)

    Considering we have wp_postmeta AS mt1, I don’t see any functional difference between the two SQL queries. I don’t think SQL can manage the fact that in ordering by mt1.meta_value, it should only use values where mt1.meta_key = 'field2'. I would expect it to order by any value in the matching results, regardless of which meta_key it relates to.

    Admittedly, I’m no SQL wiz, but I’m not convinced sorting by specific keyed fields is possible when there are multiple keys. If you know otherwise and know how to compose such an ORDER BY clause, I know how to force WP to use it. We would use the “posts_orderby” filter.

    tcaneeaglepub

    (@tcaneeaglepub)

    I am also experiencing this problem where ‘OR’ meta queries do not sort properly. Using WP version 4.8.2. It seems to only want to sort by the first named clause. Was anyone able to figure out a solution? My meta query section:

    ‘meta_query’ => array(
    ‘relation’ => ‘OR’,
    ‘cornerstone_clause’ => array(
    ‘key’ => ‘_yst_is_cornerstone’,
    ‘compare’ => ‘EXISTS’,
    ‘type’ => ‘NUMERIC’,
    ),
    ‘count_clause’ => array(
    ‘key’ => ‘erp_post_views_count’,
    ‘compare’ => ‘>’,
    ‘value’ => 0,
    ‘type’ => ‘NUMERIC’,
    ),
    ),
    ‘orderby’ => array(
    ‘cornerstone_clause’ => ‘DESC’,
    ‘count_clause’ => ‘DESC’,
    ),

Viewing 2 replies - 1 through 2 (of 2 total)

The topic ‘Order by multiple meta fields not working when using relation “OR”’ is closed to new replies.