MySQL запрос для получения категории из wp_posts

21 мая 2017 г., 20:57:48
Просмотры: 24K
Голосов: 6

Использую этот запрос для получения всех моих записей с определенным 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 для определенных категорий?

2
Комментарии

Зачем вам напрямую использовать SQL, если есть класс WP_Query, который может сделать это за вас?

Cedon Cedon
21 мая 2017 г. 21:44:02

Никогда о таком не слышал. Я изучу этот вариант. Я просто экспериментирую с массовым редактированием post_content в таблице wp_posts на локальном сервере в своем PHP-скрипте вне WordPress. Затем импортирую изменения обратно на рабочий сайт. Всё работало отлично, пока не понадобилась фильтрация по категориям.

bbruman bbruman
21 мая 2017 г. 22:04:29
Все ответы на вопрос 4
1
15

Разобрался. @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).

21 мая 2017 г. 22:58:11
Комментарии

Знание SQL всегда будет большим плюсом+

Tosin Onikute Tosin Onikute
20 мая 2018 г. 12:49:16
4

Это можно сделать с помощью класса 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; обратно к значению основного запроса.

21 мая 2017 г. 22:16:32
Комментарии

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

bbruman bbruman
21 мая 2017 г. 22:36:59

Чем ты пытаешься получить доступ, если не через WordPress?

Cedon Cedon
21 мая 2017 г. 22:38:05

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

bbruman bbruman
21 мая 2017 г. 22:43:30

Вы могли бы использовать REST API в таком случае.

Cedon Cedon
21 мая 2017 г. 23:21:25
1

Я создал запрос, который можно использовать для поиска всех связанных категорий:

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)

2 июн. 2019 г. 04:19:47
Комментарии

Это не ответ на вопрос. Речь шла о получении постов из определенной категории (название немного вводит в заблуждение).

nmr nmr
2 июн. 2019 г. 14:12:14
0

Спасибо, Дипак Шарма, благодаря вашему посту я смог сделать то, что пытался реализовать! Я внес несколько исправлений, чтобы это заработало. Хотел бы поставить лайк вашему комментарию, но у меня недостаточно баллов!

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'
29 апр. 2020 г. 19:21:44