我想查询我的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
。。。然后这个玩家(ID
158
) 将在数组中返回,尽管我要求
colortoken != blue
. 当有多个元值具有相同的键时,这似乎是一个问题,但您试图否定的不是第一个(因此,如果
blue
是第一个值而不是第二个值,或者是唯一的
colortoken
元值,然后发布
158
不会被退回)。
这似乎只是我合并时的一个问题relation => AND
使用compare => \'=\'
&;compare => \'!=\'
. 如果两个比较都是=
(或删除,因为它是隐式的),则返回的数组与预期一样,即使有多个重复的元键/值对。
我是否遗漏了什么,或者这是某种预期的行为?
最合适的回答,由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级玩家,除了那些有蓝色标记的玩家。