MySQL запрос для получения категории из wp_posts
Использую этот запрос для получения всех моих записей с определенным post_type
SELECT *
FROM wp_posts
WHERE post_type = 'product';
Как описано здесь, категория находится не в таблице wp_posts
, а в таблицах терминов wp_terms
, wp_term_relationships
, wp_term_taxonomy
При поиске категории по всем таблицам, единственное упоминание категории, которое я смог найти, было в таблице wp_terms
, которая содержит следующие столбцы
- term_id
- name
- slug
- term_group
Поиск перекрестных ссылок на это в других таблицах и их связь с wp_posts вызывает некоторые сложности.
Я думаю, что нужно искать term_id
, так как это похоже на внешний ключ, но единственное его упоминание находится в wp_term_taxonomy
, и единственная информация, которую я могу найти в таблице, связанная с моей категорией (или скорее term_id
) это
- term_taxonomy_id
- term_id
- taxonomy
- description
- parent
- count
Таким образом, единственная информация, которую я могу получить из этого, сообщает мне, что моя term_id
taxonomy
является product_cat
и в поле count
указывается, сколько постов у меня есть для этой конкретной категории.
Зная немного о MySQL, я понимаю, что если есть надежда сделать это, мне нужно модифицировать мой запрос и сделать один или два JOIN
.
Но я нахожу очень ограниченную информацию о том, за что именно можно зацепиться.
Вот структура wp_posts
`wp_posts` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`post_author` bigint(20) unsigned NOT NULL DEFAULT '0',
`post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`post_date_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`post_content` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL,
`post_title` text COLLATE utf8mb4_unicode_520_ci NOT NULL,
`post_excerpt` text COLLATE utf8mb4_unicode_520_ci NOT NULL,
`post_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'publish',
`comment_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'open',
`ping_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'open',
`post_password` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`post_name` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`to_ping` text COLLATE utf8mb4_unicode_520_ci NOT NULL,
`pinged` text COLLATE utf8mb4_unicode_520_ci NOT NULL,
`post_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`post_modified_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`post_content_filtered` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL,
`post_parent` bigint(20) unsigned NOT NULL DEFAULT '0',
`guid` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`menu_order` int(11) NOT NULL DEFAULT '0',
`post_type` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'post',
`post_mime_type` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`comment_count` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `post_name` (`post_name`(191)),
KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`),
KEY `post_parent` (`post_parent`),
KEY `post_author` (`post_author`)
)
Возможно ли вообще модифицировать мой запрос, чтобы получать только строки таблицы wp_posts
для определенных категорий?
Разобрался. @belinus, вероятно, будет решением для вас, если вам нужно сделать это в рамках WordPress.
Что касается чистого SQL-запроса, с которым можно поэкспериментировать, я нашел этот вариант, немного его модифицировал, и он возвращает все товары для определенной категории.
Для этого потребуются три таблицы: wp_posts
, wp_term_relationships
и wp_term_taxonomy
.
SELECT *
FROM wp_posts
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
LEFT JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
WHERE wp_term_taxonomy.term_id IN (307)
GROUP BY wp_posts.ID
Просто замените 307
на term_id
категории, для которой хотите получить результаты. Его можно найти, выполнив поиск в столбце name
таблицы wp_terms
, и он вернет связанный идентификатор термина.
Также можно вернуть несколько категорий, просто перечислите их через запятую в условии WHERE
, например: WHERE wp_term_taxonomy.term_id IN (307, 450, 200, 99)
.

Это можно сделать с помощью класса WP_Query
. Если вам нужно просто получить все записи по категории, вы можете сделать это, используя ID или слаг.
$args = array(
'cat' => 1,
);
$new_query = new WP_Query( $args );
ИЛИ
$args = array(
'cat_name' => 'news',
);
$new_query = new WP_Query( $args );
Далее вы пишете стандартный цикл, но с одним исключением:
<?php if ( $new_query->have_posts() ) : ?>
<?php while ( $new_query->have_posts() ) : $new_query->the_post(); ?>
// Код для вывода записи
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else : ?>
// Записи не найдены
<?php endif; ?>
Необходимо включить вызов функции wp_reset_postdata();
, которая сбросит global $post;
обратно к значению основного запроса.

Спасибо! Я приму этот ответ, если не смогу найти решение, которое не зависит от фреймворка WP. Хочу еще немного изучить этот вопрос — казалось бы, должен быть способ вручную соединить таблицы через запрос... но возможно, это не так

Я просто экспортирую нужные таблицы из WordPress и провожу интенсивное тестирование и эксперименты с ними на локальном сервере. В основном, чтобы попробовать массово отредактировать столбец post_content и потом вернуть изменения на боевой сервер. Поскольку post_content — это просто блоки HTML-кода, фреймворк не требовался (до этого момента, возможно).

Я создал запрос, который можно использовать для поиска всех связанных категорий:
SELECT * FROM wpra_term_relationships
INNER JOIN wpra_term_taxonomy ON (wpra_term_taxonomy.term_taxonomy_id=wpra_term_relationships.term_taxonomy_id AND wpra_term_taxonomy.taxonomy='category')
INNER JOIN wpra_terms ON (wpra_terms.term_id=wpra_term_taxonomy.term_id )
WHERE object_id='273960'
Просто замените 273960 на ID вашей записи (POST ID)

Спасибо, Дипак Шарма, благодаря вашему посту я смог сделать то, что пытался реализовать! Я внес несколько исправлений, чтобы это заработало. Хотел бы поставить лайк вашему комментарию, но у меня недостаточно баллов!
SELECT * FROM wp_term_relationships INNER JOIN wp_term_taxonomy ON (wp_term_taxonomy.term_taxonomy_id=wp_term_relationships.term_taxonomy_id AND wp_term_taxonomy.taxonomy='product_cat') INNER JOIN wp_terms ON (wp_terms.term_id=wp_term_taxonomy.term_id ) WHERE object_id='61170'
