我正在使用pre_get_posts
钩子在查询运行之前更改查询。
所讨论的职位是绩效,因此是基于日期和时间的。
我想更改查询以获取将来的所有性能(即日期大于今天或日期为今天且时间大于或等于当前时间)。这是可行的,但当我试图主要按日期升序,其次按时间升序排序时,顺序并不像预期的那样。
这些帖子是按日期正确排序的,但只有今天的表演是按时间正确排序的,其他日子的表演时间是随机排序的。
我认为这与相对于orderby参数的meta\\u查询数组的命名有关,但无法解决此问题。
我的代码如下:
//No limit on number to get
$query->set(\'posts_per_page\', -1);
//Get future performances
$query->set(\'meta_query\', array(
\'relation\' => \'AND\',
array(
\'relation\' => \'OR\',
\'performance_date\' => array(
\'key\' => \'performance_date\',
\'value\' => date(\'Ymd\'),
\'compare\' => \'>\',
\'type\' => \'NUMERIC\'
),
array(
\'relation\' => \'AND\',
\'performance_date\' => array(
\'key\' => \'performance_date\',
\'value\' => date(\'Ymd\'),
\'compare\' => \'=\',
\'type\' => \'NUMERIC\'
),
\'performance_time\' => array(
\'key\' => \'performance_time\',
\'value\' => date(\'H:i\'),
\'compare\' => \'>=\',
\'type\' => \'TIME\'
)
)
)
));
//Order by closest performance first
$query->set(\'orderby\', array(
\'performance_date\' => \'ASC\',
\'performance_time\' => \'ASC\'
));
最合适的回答,由SO网友:birgire 整理而成
我想如果你有performance_datetime
自定义字段,因为这样可以简化元查询。
以下只是一个有趣的演示:
据我所知,在wp_posts
表,即wp_postmeta
, mt1
和mt2
. 但是meta_key
对于这些联接的表,字段并不总是performance_date
或performance_time
. 因此,在其中一个表中,按meta值排序对于WP_Query
.
仅在这种情况下,硬编码的解决方法可以是:
ORDER BY
CASE
WHEN wp_postmeta.meta_key = \'performance_date\'
THEN CAST( wp_postmeta.meta_value AS SIGNED )
WHEN mt1.meta_key = \'performance_date\'
THEN CAST( mt1.meta_value AS SIGNED )
WHEN mt2.meta_key = \'performance_date\'
THEN CAST( mt2.meta_value AS SIGNED )
ELSE
wp_postmeta.post_id
END ASC,
CASE
WHEN wp_postmeta.meta_key = \'performance_time\'
THEN CAST( wp_postmeta.meta_value AS TIME)
WHEN mt1.meta_key = \'performance_time\'
THEN CAST( mt1.meta_value AS TIME)
WHEN mt2.meta_key = \'performance_time\'
THEN CAST( mt2.meta_value AS TIME)
ELSE
wp_postmeta.post_id
END ASC
您可以通过以下方式进行测试:
$query->set(\'orderby\', \'performance\' );
以下未测试插件支持自定义排序:
add_filter( \'posts_orderby\', function( $orderby, \\WP_Query $q )
{
if( \'performance\' !== $q->get( \'orderby\' ) )
return $orderby;
global $wpdb;
$order = ( \'ASC\' === strtoupper( $q->get( \'order\' ) ) ) ? \'ASC\' : \'DESC\';
$orderby = "
CASE
WHEN {$wpdb->postmeta}.meta_key = \'performance_date\'
THEN CAST( {$wpdb->postmeta}.meta_value AS SIGNED )
WHEN mt1.meta_key = \'performance_date\'
THEN CAST( mt1.meta_value AS SIGNED )
WHEN mt2.meta_key = \'performance_date\'
THEN CAST( mt2.meta_value AS SIGNED )
ELSE
{$wpdb->postmeta}.post_id
END {$order},
CASE
WHEN {$wpdb->postmeta}.meta_key = \'performance_time\'
THEN CAST( {$wpdb->postmeta}.meta_value AS TIME)
WHEN mt1.meta_key = \'performance_time\'
THEN CAST( mt1.meta_value AS TIME)
WHEN mt2.meta_key = \'performance_time\'
THEN CAST( mt2.meta_value AS TIME)
ELSE
{$wpdb->postmeta}.post_id
END {$order}";
return $orderby;
}, 10, 2 );
请注意,这是相当不灵活的,因为当您更改查询时,这可能不起作用。但希望您可以根据自己的需要进行调整,甚至使其更加灵活。