WP_QUERY:将SQL函数应用于元字段值

时间:2018-02-05 作者:Kuraga

假设我正在按元字段进行排序查询:

new WP_Query( array(
    \'meta_query\' => array(
        \'state_clause\' => array(
            \'key\' => \'state\'
        ),
    ),
    \'orderby\' => array( 
        \'state_clause\' => \'DESC\',
    )
) );
我可以在订购之前应用SQL函数吗(无需手动SQL查询)?按not命令state 但是LTRIM(state)?

1 个回复
最合适的回答,由SO网友:janh 整理而成

您可以使用过滤器posts_orderby. 举个简单的例子:

add_filter(\'posts_orderby\', \'apply_sql_on_order\', 10, 2 );
function apply_sql_on_order($orderby, $query) {
    if(is_array($query->query_vars["orderby"]) && array_key_exists("apply_sql", $query->query_vars["orderby"])) {
        $orderby = preg_replace("/(.*) (ASC|DESC)/", $query->query_vars["orderby"]["apply_sql"] . "($1) $2", $orderby);
    }
    return $orderby;
}

$query = new WP_Query( array(
    \'meta_query\' => array(
        \'state_clause\' => array(
            \'key\' => \'state\'
        ),
    ),
    \'orderby\' => array( 
        \'state_clause\' => \'DESC\',
        "apply_sql" => "LTRIM"
    )
) );
会把你从

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) WHERE 1=1  AND ( 
  wp_postmeta.meta_key = \'state\'
) AND wp_posts.post_type = \'post\' AND (wp_posts.post_status = \'publish\') GROUP BY wp_posts.ID ORDER BY CAST(wp_postmeta.meta_value AS CHAR) DESC LIMIT 0, 10

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) WHERE 1=1  AND ( 
  wp_postmeta.meta_key = \'state\'
) AND wp_posts.post_type = \'post\' AND (wp_posts.post_status = \'publish\') GROUP BY wp_posts.ID ORDER BY LTRIM(CAST(wp_postmeta.meta_value AS CHAR)) DESC LIMIT 0, 10
WP只会忽略orderby数组中的“apply\\u sql”,因为它在这个WP\\u查询的上下文中不是有效的order子句。

这显然是一个非常粗糙的版本,如果在orderby. 在这种情况下,不进行某种抽象,只让过滤器回调操作SQL可能更容易。

如果您想对此进行扩展,查看源代码可能会有所帮助。大部分魔法都发生在parse_orderby 在WP\\U查询中。您可以创建自己的版本,基本上模仿它,并在旁边添加一些奇特的东西(可能未设置orderby 在查询时使用pre_get_posts 然后将幻想的order子句添加回posts_orderby).

结束

相关推荐

如何以编程方式或使用SQL Query创建WooCommerce产品?

我想在不使用管理面板的情况下向购物车添加有问题的产品。添加到购物车,然后使用php代码签出。那么我如何实现它,我应该把代码放在哪里呢?我正在插件文件中编写一个php脚本,接受插件中的post数据。我的代码是 <?php var_dump($_POST); $post_id = wp_insert_post( array( \'post_title\' => \'Great new product\', \'pos