Как выбрать записи с определенными тегами / категориями в WordPress

Это очень специфический вопрос, касающийся MySQL, реализованного в WordPress.

Я пытаюсь разработать плагин, который будет показывать (выбирать) сообщения с определенными "тегами" и принадлежащими к определенным "категориям" (и то и другое несколько).

Мне сказали, что это невозможно из-за способа хранения категорий и тегов:

  1. wp_posts содержит список сообщений, каждое сообщение имеет «ID»
  2. wp_terms содержит список терминов (категорий и тегов). У каждого термина есть TERM_ID
  3. wp_term_taxonomy имеет список терминов с их TERM_ID и определение Таксономии для каждого из них (категория или тег)
  4. wp_term_relationships имеет связи между терминами и сообщениями

Как я могу присоединиться к таблицам, чтобы получить все сообщения с тегами "Nuclear" и "Deals", которые также относятся к категории "Category1"?


person yoavf    schedule 26.08.2008    source источник


Ответы (6)


Я не так тебя поняла. Я думал, ты хочешь Ядерную или Сделки. Ниже представлены только ядерные материалы и сделки.

select p.*
from wp_posts p, wp_terms t, wp_term_taxonomy tt, wp_term_relationship tr,
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship tr2
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship tr2

where p.id = tr.object_id and t.term_id = tt.term_id and tr.term_taxonomy_id = tt.term_taxonomy_id

and p.id = tr2.object_id and t2.term_id = tt2.term_id and tr2.term_taxonomy_id = tt2.term_taxonomy_id

and p.id = tr3.object_id and t3.term_id = tt3.term_id and tr3.term_taxonomy_id = tt3.term_taxonomy_id

and (tt.taxonomy = 'category' and tt.term_id = t.term_id and t.name = 'Category1')
and (tt2.taxonomy = 'post_tag' and tt2.term_id = t2.term_id and t2.name = 'Nuclear')
and (tt3.taxonomy = 'post_tag' and tt3.term_id = t3.term_id and t3.name = 'Deals')
person Eric    schedule 27.08.2008

Какая грубая структура БД.

В любом случае, я бы сделал что-то вроде этого (обратите внимание, я предпочитаю EXISTS объединениям, но вы можете переписать их как объединения, если хотите; большинство анализаторов запросов все равно свернут их в один и тот же план запроса). Возможно, вам, так или иначе, придется потрудиться, чтобы это сработало ...

SELECT *
  FROM wp_posts p
 WHERE EXISTS( SELECT *
                 FROM wp_term_relationship tr
                WHERE tr.object_id = p.id
                  AND EXISTS( SELECT *
                                FROM wp_term_taxonomy tt
                               WHERE tt.term_taxonomy_id = tr.term_taxonomy_id
                                 AND tt.taxonomy         = 'category'
                                 AND EXISTS( SELECT *
                                               FROM wp_terms t
                                              WHERE t.term_id = tt.term_id
                                                AND t.name    = "Category1" 
                                           )
                            )
                  AND EXISTS( SELECT *
                                FROM wp_term_taxonomy tt
                               WHERE tt.term_taxonomy_id = tr.term_taxonomy_id
                                 AND tt.taxonomy         = 'post_tag'
                                 AND EXISTS( SELECT *
                                               FROM wp_terms t
                                              WHERE t.term_id = tt.term_id
                                                AND t.name    = "Nuclear" 
                                           )
                                 AND EXISTS( SELECT *
                                               FROM wp_terms t
                                              WHERE t.term_id = tt.term_id
                                                AND t.name    = "Deals" 
                                           )
                            )
            )
person Matt Rogish    schedule 26.08.2008

Попробуй это:

select p.*
from wp_posts p, 
wp_terms t, wp_term_taxonomy tt, wp_term_relationship tr
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship tr2

where p.id = tr.object_id
and t.term_id = tt.term_id
and tr.term_taxonomy_id = tt.term_taxonomy_id

and p.id = tr2.object_id
and t2.term_id = tt2.term_id
and tr2.term_taxonomy_id = tt2.term_taxonomy_id

and (tt.taxonomy = 'category' and tt.term_id = t.term_id and t.name = 'Category1')
and (tt2.taxonomy = 'post_tag' and tt2.term_id = t2.term_id and t2.name in ('Nuclear', 'Deals'))

По сути, я использую две копии соответствующих дочерних таблиц - terms, term_taxonomy и term_relationship. Один экземпляр применяет ограничение «Категория1», другой - ограничение «Ядерная промышленность» или «Сделки».

Кстати, что это за проект с сообщениями о ядерных сделках? Вы пытаетесь внести нас в какой-то правительственный список? ;)

person Eric    schedule 26.08.2008
comment
Это фантастическое решение - person Lenin Zapata; 25.06.2019

Поэтому я попробовал оба варианта на своей базе данных WordPress. Я искал в своих сообщениях категорию «Техника» с тегами «Perl» И «Программирование».

Эрик сработал, как только я добавил пропущенную запятую в начальный оператор выбора. Он вернул 3 записи. Проблема в том, что раздел, который ищет "post_tag", на самом деле работает как вариант ИЛИ. В одном из моих постов был только один тег, а не оба. Также было бы хорошо сделать SELECT DISTINCT.

Я попробовал версию Мэтта, но она продолжала возвращать пустой набор. Я могу попробовать с этим "подтасовывать".

person Scott Gottreu    schedule 26.08.2008

Спасибо @Eric, все работает! Всего несколько исправлений кода для использования в будущем:

  • первые операторы выбора пропускают кому после wp_term_relationship tr2
  • В том же состоянии выбора необходимо изменить следующее:
wp_terms t2, wp_term_taxonomy tt2, wp_term_relationship 

tr2

должно быть

wp_terms t3, wp_term_taxonomy tt3, wp_term_relationship 

tr3
person yoavf    schedule 28.08.2008

Действительно отличный ответ .. мне очень помог ..

отличный bcoz., это дало мне базовый подход к построению моего сложного запроса!

одно небольшое исправление, для таких готовых пользователей, как я :)

"wp_term_relationship" выдаст сообщение "ошибка не существует". Используйте wp_term_relationships, так как это правильное имя таблицы.

Спасибо Эрик

person Community    schedule 05.02.2009