组合等于和非等于时,META_QUERY WITH RELATION=AND不能按预期工作

时间:2018-05-15 作者:indextwo

我想查询我的player 对于所有那些没有colortoken 元值(请注意player 可以有多个colortoken meta\\u键)。我想我可以做到这一点:

$args = array(
    \'post_type\'         => \'player\',
    \'post_status\'       => \'any\',
    \'posts_per_page\'    => 1,

    \'meta_query\'        => array(
        \'relation\' => \'AND\',
        array(
            \'key\'     => \'playerlevel\',
            \'value\'   => 12,
        ),
        array(
            \'key\'       => \'colortoken\',
            \'value\'     => \'blue\',
            \'compare\' => \'!=\',
        ),
    ),
);

$playersQuery = get_posts($args);
这将返回所有12级玩家,但don\'t 喝杯蓝色的colortoken. 这很有效。。。但前提是player 有一个colortoken. 如果我有player 带有两个colortoken meta\\u值:

Post ID     => 158
playerlevel => 12
colortoken  => red
colortoken  => blue
。。。然后这个玩家(ID158) 将在数组中返回,尽管我要求colortoken != blue. 当有多个元值具有相同的键时,这似乎是一个问题,但您试图否定的不是第一个(因此,如果blue 是第一个值而不是第二个值,或者是唯一的colortoken 元值,然后发布158 不会被退回)。

这似乎只是我合并时的一个问题relation => AND 使用compare => \'=\' &;compare => \'!=\'. 如果两个比较都是= (或删除,因为它是隐式的),则返回的数组与预期一样,即使有多个重复的元键/值对。

我是否遗漏了什么,或者这是某种预期的行为?

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

该玩家确实有一个不是蓝色的彩色标记,因为他有一个红色的。:)

SQL,以及扩展到WP\\U查询系统,是非常文字化的。它是选择一组拥有非蓝色色标且等级为12的玩家。这并不是排除拥有蓝色标记的玩家,而是选择所有非蓝色标记的玩家。

在WP\\u查询中无法完成此处所需的操作。虽然它是SQL之上的一个很好的抽象,但它并不是一个完美的抽象,它不能表示所有可能的查询。特别是,WP\\u查询旨在根据参数选择要包含的帖子。在这里,您希望排除一组基于蓝色colortoken的帖子,而meta\\u查询无法做到这一点。

以下是您的查询在WP\\U query解析后的样子(稍微简化):

SELECT wp_posts.ID FROM wp_posts 
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) 
INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) 
WHERE 1=1 AND 
( 
( wp_postmeta.meta_key = \'playerlevel\' AND wp_postmeta.meta_value = \'12\' ) AND 
( mt1.meta_key = \'colortoken\' AND mt1.meta_value != \'blue\' ) 
) AND 
wp_posts.post_type = \'player\' AND 
((wp_posts.post_status <> \'trash\' AND wp_posts.post_status <> \'auto-draft\')) 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC LIMIT 0, 1
要主动排除蓝色标记,需要使用子查询来排除它们。WP\\u Query不能很好地执行子查询。以下是您想要获得的帖子:

SELECT wp_posts.ID FROM wp_posts 
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) 
WHERE 1=1 AND 
wp_posts.ID NOT IN ( 
SELECT post_id FROM wp_postmeta WHERE 
meta_key = \'colortoken\' AND meta_value = \'blue\' 
) AND
( wp_postmeta.meta_key = \'playerlevel\' AND wp_postmeta.meta_value = \'12\' ) AND 
wp_posts.post_type = \'player\' AND 
((wp_posts.post_status <> \'trash\' AND wp_posts.post_status <> \'auto-draft\')) 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC LIMIT 0, 1
这基本上会选择所有12级玩家,除了那些有蓝色标记的玩家。

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post