$Wpdb POST元查询不能处理多个元键和值?

时间:2018-02-11 作者:Umar Tanveer

我正在尝试从此查询中获取帖子ID

$sql_query = "SELECT post_id from ".$wpdb->postmeta." 
WHERE (meta_key LIKE \'habitat_types_%_habitat_type\' AND meta_value IN(\'Coastal Sage Scrub\')) 
AND (meta_key LIKE \'state\' AND meta_value IN(\'Oregon\')) group by post_id";
但此代码返回空数组。当我查询其中一个habitat\\u类型或状态时,它工作正常,但不能一起工作。

这是我的完整代码:

<?php

global $wpdb;

$sql_query = "SELECT post_id from ".$wpdb->postmeta." WHERE (meta_key LIKE \'habitat_types_%_habitat_type\' AND meta_value IN(\'Coastal Sage Scrub\')) AND (meta_key LIKE \'state\' AND meta_value IN(\'Oregon\')) group by post_id";

$result =  $wpdb->get_results($sql_query,ARRAY_A);

print_r($result);

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

首先,让我指出几个问题。

SQL语句有两个不同的条件,不能同时为true:meta key=“state”和meta\\u key,如“habitation\\u types\\u%\\ u habitat\\u type”。为了正确地做到这一点,post meta必须内部连接到自身上(请参阅下面的更多信息)。

您没有在内部加入posts表,这意味着您可能正在获取孤立的post meta(甚至不属于post的post meta)。此外,您无法按帖子类型或帖子状态进行筛选。至少,您需要将post\\u meta内部连接到自身,以获得您想要的结果,但下面我将post\\u meta内部连接到posts,然后再次将post\\u meta连接到posts。

如果没有通配符元键“habitat\\u types\\u%\\ u habitat\\u type”,您可以使用get\\u posts()或新的WP\\u查询(其工作方式大致相同)来获取相同的内容,但方式要简单得多。

您能否提供有关“habitat\\u types\\u%\\ u habitat\\u type”元键的更多信息?为什么我们在这里使用通配符,有多少种不同的可能性?

下面是一个SQL解决方案:

global $wpdb;
$query = \'\';
$vars = array();

// select statement gets a bit complicated
$query .= \'SELECT *, pm1.meta_key AS mk1, pm1.meta_value AS mv1, pm2.meta_key AS mk2, pm2.meta_value AS mv2 \'; // each line has a space at the end
$query .= \'FROM \' . $wpdb->posts . \' AS posts \';
$query .= \'INNER JOIN \' . $wpdb->postmeta . \' AS pm1 ON posts.ID = pm1.post_id \';
$query .= \'INNER JOIN \' . $wpdb->postmeta . \' AS pm2 ON posts.ID = pm2.post_id \';

// placeholder \'where\' statement, so all other ones can use \'and\'
$query .= \'WHERE 1 = 1 \';

// %s and %d get replaced by elements in the $vars array, the number of %s/%d\'s should be the same 
// as the length of the array. Its only meant to be used when the $vars come from user input or maybe a variable.
// but here i\'m just using them for hardcoded values anyways.
$query .= \'AND posts.post_status = %s \';
$vars[] = \'publish\';

$query .= \'AND posts.post_type = %s \';
$vars[] = \'post\'; // insert your own post type here

// first post meta join
$query .= \'AND pm1.meta_key LIKE "habitat_types_%_habitat_type" \';    
$query .= \'AND pm1.meta_value = %s \';
$vars[] = \'Coastal Sage Scrub\';

// second post meta join
$query .= \'AND pm2.meta_key LIKE "state" \';
$query .= \'AND pm2.meta_value = %s \';
$vars[] = \'Oregon\';

$query .= \'GROUP BY posts.ID \';
$query .= \'ORDER BY posts.post_date \';
$query .= \' ;\'; // semi-colon needed or query will be invalid

// note: if using $wpdb->prepare where $vars is empty, error will be thrown.
$r = $wpdb->get_results( $wpdb->prepare( $query, $vars ) );

if ( $r ) {
    foreach ( $r as $dbRow ) {
        echo $dbRow->ID; // should be post ID
        echo $dbRow->mv1; // this should be Coastal Sage Scrub
        echo $dbRow->mv2; // should be Oregon
    }
}
如果没有“habitat\\u types\\u%\\ u habitat\\u type”元键中的通配符,那么更简单的解决方案如下(请参见下面代码中的注释)

$args = array(
    \'post_type\' => \'post\', // insert your own post type here
    \'post_status\' => \'publish\', // so we dont get posts from the trash bin
    \'posts_per_page\' => -1,
    \'meta_query\' => array(
        \'relation\' => \'AND\',
        array(
            \'key\' => \'state\',
            \'value\' => \'Oregon\',
            \'compare\' => \'=\',
        ),
        // I dont think this will work:
//        array(
//            \'key\' => \'habitat_types_%_habitat_type\',
//            \'value\' => \'Oregon\',
//            \'compare\' => \'=\',
//        ),
        // this would work, but its probably not what you want
        array(
            \'key\' => \'habitat_type\',
            \'value\' => \'Coastal Sage Scrub\',
            \'compare\' => \'=\',
        ),
    )
);

$posts = get_posts( $args );

if ( $posts ) {
    foreach ( $posts as $p ) {
        echo $p->ID; // post ID
        $state = get_post_meta( $p->ID, \'state\', true );
        echo $state; // should be Oregon
        // getting "habitat_types" is a bit tricky because i don\'t know why there\'s a wildcard in the meta key
    }
}

// for the sake of understanding how things work, I recommend trying this:
// $wpq = new WP_Query( $args );
// var_dump( $wpq );
// Look for the \'request\' index of $wpq (can\'t remember if its in $wpq->query->request, or just $wpq->request)
// The request will be the SQL statement. Play around with the meta query to see how your SQL changes. You\'ll notice it looks pretty similar to the SQL statement in the first example.

结束

相关推荐

通过unctions.php将<meta>标记添加到<head>部分

我已经开发了一个自定义主题,它基本上是一个供客户使用的4页宣传册网站,我通过构建自定义帖子类型(gzip-via)成功删除了一些插件。htaccess和通过gulp等缩小。我会在网站上保留安全插件,但我想删除Yoast,它带来的唯一好处是,考虑到网站的优化程度,它允许我添加meta 用于SEO目的的每个页面的标记和代码片段。是否有一个函数可以添加到我的函数中。允许我添加的php文件<meta> 通过页面id标记到不同页面?当一个人在谷歌上搜索这个主题时,你得到的只是插件文章,或者关于通用wp元