多个自定义字段存储为meta_keys,如何与帖子连接?

时间:2011-08-16 15:00:47

标签: mysql wordpress join logic

我最近发布了一个关于连接两个查询以省略在第二个中找到的元素的问题:

MYSQL - How to join two queries to omit elements found in the second query (or perhaps any better solution?)

现在我想知道如何查看一些meta_keys及其相应的值来实现其他目的。

我本质上是使用自定义字段构建一个事件系统,简化,事件将具有:

  • 开始日期
  • 结束日期
  • 正在进行(是或否)

这些存储为

-----------
wp_postmeta
-----------
meta_key
meta_value
post_id

e.g。

-----------
wp_postmeta
-----------
Start Date
2011-07-30
10

-----------
wp_postmeta
-----------
End Date
2011-08-30
10

-----------
wp_postmeta
-----------
Ongoing
Yes
10

我的困惑在于尝试查看多个 wp_postmeta 条目并将它们与相应的帖子连接起来。

例如,我想找到以下帖子:

  • 开始日期>今天
  • 结束日期>今天
  • 正在进行=是

基于上一个问题,我正在尝试此查询:

SELECT * FROM wp_posts, wp_postmeta
WHERE wp_posts.ID = wp_postmeta.post_id

AND wp_posts.ID IN (
SELECT post_id FROM wp_postmeta
WHERE wp_postmeta.meta_key = 'Start Date'
AND wp_postmeta.meta_value > NOW())

AND wp_posts.ID IN (
SELECT post_id FROM wp_postmeta
WHERE wp_postmeta.meta_key = 'Ongoing'
AND wp_postmeta.meta_value = 'Yes')

AND wp_posts.ID IN (
SELECT post_id FROM wp_postmeta
WHERE wp_postmeta.meta_key = 'End Date'
AND wp_postmeta.meta_value > NOW())

哪个不起作用。

我觉得必须有一种方法可以找到所有相关的meta_keys并将它们的值连接到post表,因此可以更容易地访问它。例如,是否可以找到'开始日期'的meta_value并将其加入wp_posts,其列标题为 start_date_value 或类似名称?

或者我该如何处理这个问题?


使用@karevn的答案,我提出了以下代码,它完全符合我的要求:

$query = array(
        'category_name' => 'event',
        'meta_query' => array(
            'relation' => 'AND',
            array(
                'key' => 'Start Date',
                'value' => $today,
                'compare' => '>'
            ),
            array(
                'key' => 'End Date',
                'value' => $today,
                'compare' => '>'
            ),
            array(
                'key' => 'Ongoing',
                'value' => 'Yes',
                'compare' => '='
            ),
        )
    );

我认为这是wordpress的一个非常强大的功能。

2 个答案:

答案 0 :(得分:1)

您可以将WP_Query类与meta_query选项一起使用,并避免编写自己的SQL。见食典:http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters。它应该是WordPress中更好的方式。您的查询看起来非常像这样:

$query = new WP_Query(array('meta_compare' => array(
    array('key' => 'Start Date', 'compare' => '>', 'type' => 'DATE', 'value' => $today),
    array('key' => 'End Date', 'compare' => '>', 'type' => 'DATE', 'value' = $today),
    array('key' => 'Ongoing', 'value' => 'Yes')));

使用此代码的副作用是其结果可能由DB缓存插件缓存。

答案 1 :(得分:1)

不确定为什么你有多行。如果您提供查询生成的表数据和样本结果的示例,则会有所帮助。查询似乎是正确的。


注意:您使用的隐式JOIN语法为WHERE

    FROM wp_posts, wp_postmeta
WHERE wp_posts.ID = wp_postmeta.post_id

不是最佳做法。最好使用显式JOIN

    FROM wp_posts
      JOIN wp_postmeta
        ON wp_posts.ID = wp_postmeta.post_id

警告:something IN (SELECT x FROM y)不会导致MySQL中出现最佳查询计划。因此,您最好将其重写(效率):

SELECT * 
FROM wp_posts
  JOIN wp_postmeta
    ON wp_posts.ID = wp_postmeta.post_id

WHERE EXISTS (
  SELECT * 
  FROM wp_postmeta
  WHERE wp_postmeta.post_id = wp_posts.ID         
  AND wp_postmeta.meta_key = 'Start Date'
  AND wp_postmeta.meta_value > NOW())

AND EXISTS (
  SELECT * 
  FROM wp_postmeta
  WHERE wp_postmeta.post_id = wp_posts.ID         
  AND wp_postmeta.meta_key = 'Ongoing'
  AND wp_postmeta.meta_value = 'Yes')

AND EXISTS (
  SELECT * 
  FROM wp_postmeta
  WHERE wp_postmeta.post_id = wp_posts.ID    
  AND wp_postmeta.meta_key = 'End Date'
  AND wp_postmeta.meta_value > NOW())