Несколько пользовательских полей хранятся как meta_keys, как связаться с постом? - PullRequest
0 голосов
/ 16 августа 2011

Недавно я опубликовал вопрос о соединении двух запросов, чтобы пропустить элементы, найденные в секунду:

MYSQL - Как объединить два запроса, чтобы пропустить элементы, найденные во втором запросе (или, возможно, какое-нибудь лучшее решение?)

Теперь мне интересно, как посмотреть количество мета-ключей и их соответствующих значений, чтобы достичь чего-то еще.

Я по сути строю систему событий с настраиваемыми полями, упрощенно, событие будет иметь:

  • Дата начала
  • Дата окончания
  • Текущий (Да или Нет)

Они хранятся как

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

, например

-----------
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 и соединить их значения с таблицей записей, чтобы к ним было проще обращаться. Например, возможно ли найти значение 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 ]

1 голос
/ 18 августа 2011

Не уверен, почему у вас есть несколько строк. Если вы предоставите образец данных таблиц и результаты, полученные в результате запроса, это поможет. Запрос кажется правильным.


Примечание: неявный синтаксис 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())
1 голос
/ 17 августа 2011

Вы можете использовать класс 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')));

Побочным эффектом использования этого кода является то, что его результаты могут быть кэшированы плагином кэширования БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...