首先,让我指出几个问题。
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.