查询的一个问题是,self连接与WHERE
提供一个交叉数据集(由DISTINCT
), 所以使用起来会更简单wp_post
作为连接与关键点精确匹配的连接的基础,例如
SELECT p.ID, key1.meta_value as prog_ongoing, key2.meta_value as prog_date_start
FROM $wpdb->posts p
INNER JOIN $wpdb->postmeta key1
ON key1.post_id = p.ID
AND key1.meta_key = %s
INNER JOIN $wpdb->postmeta key2
ON key2.post_id = p.ID
AND key2.meta_key = %s
它给出了一个线性数据集。然后您可以添加(或不添加)
WHERE
限制数据的条款:
WHERE key1.meta_value IS TRUE OR key2.meta_value >= %d
对于
ORDER BY
使用
CASE
语句单字段排序:
ORDER BY CASE
WHEN key2.meta_value >= %d THEN CONCAT(\'A\', key2.meta_value)
WHEN key1.meta_value AND key2.meta_value THEN CONCAT(\'B\', key2.meta_value)
WHEN key1.meta_value THEN \'C\'
ELSE \'D\'
END ASC
或者类似的,上述需要
prepare
参数为:
$meta_key1,
$meta_key2,
$start_date, $start_date
您可以使用
posts_orderby
使用筛选器执行类似操作
WP_Query
(虽然它使用了一种生成交叉数据集的方法,但要求它必须使用
GROUP BY
, 这会使事情复杂化)。比如说
$args = array(
\'posts_per_page\' => -1,
\'post_type\' => \'cpt_program\',
\'meta_query\' => array(
\'ongoing\' => array(
\'key\' => \'prog_ongoing\',
),
\'start_date\' => array(
\'key\' => \'prog_date_start\',
)
),
);
add_filter( \'posts_orderby\', $func = function ( $orderby, $query ) {
$start_date = date(\'Ymd\');
global $wpdb;
$orderby = $wpdb->prepare(
"
CASE
WHEN mt1.meta_value >= %d THEN CONCAT(\'A\', mt1.meta_value)
WHEN {$wpdb->postmeta}.meta_value AND mt1.meta_value THEN CONCAT(\'B\', mt1.meta_value)
WHEN {$wpdb->postmeta}.meta_value THEN \'C\'
ELSE \'D\'
END ASC
"
, $start_date
);
return $orderby;
}, 10, 2 );
$query = new WP_Query( $args );
remove_filter( \'posts_orderby\', $func, 10, 2 );