Вопрос или проблема
Я пытаюсь сделать запрос, чтобы получить первые 3 категории с наибольшим количеством постов на пользователя, но до сих пор безуспешно. Вот где я сейчас:
SELECT DISTINCT(terms.term_id) as term_ID, terms.name, terms.slug, posts.post_author, t0.count_id
FROM wp_posts as posts
JOIN wp_term_relationships as relationships ON posts.ID = relationships.object_ID
JOIN wp_term_taxonomy as tax ON relationships.term_taxonomy_id = tax.term_taxonomy_id
JOIN wp_terms as terms ON tax.term_id = terms.term_id
JOIN (
SELECT COUNT(*) as count_id, count_terms.term_id
FROM wp_posts as posts_count
JOIN wp_term_relationships as count_relationships ON posts_count.ID = count_relationships.object_ID
JOIN wp_term_taxonomy as count_tax ON count_relationships.term_taxonomy_id = count_tax.term_taxonomy_id
JOIN wp_terms as count_terms ON count_tax.term_id = count_terms.term_id
WHERE count_tax.taxonomy = "category"
AND posts_count.post_status = "publish"
AND posts_count.post_author in (1,2,3)
group by count_terms.term_id
) as t0 on posts.post_author in (1,2,3)
WHERE tax.taxonomy = "category"
AND posts.post_status = "publish"
AND posts.post_author in (1,2,3)
Это возвращает пользователей с категориями, но с общей суммой всех постов в этих категориях для этих пользователей. А мне нужны первые 3 категории с наибольшим количеством постов на пользователя. Есть идеи, как это сделать?
Ваш вопрос немного неясен, но я читаю его следующим образом: дан автор, и вы хотите знать три категории, в которых он опубликовал больше всего постов. Давайте используем wp_query
, чтобы добиться этого.
$author="johndoe";
$author_posts = new WP_Query (array (
'author' => $author,
'posts_per_page'=>-1,
));
Теперь у нас есть массив всех постов этого автора. К сожалению, невозможно упорядочить их по категории (поскольку у поста может быть несколько категорий), не говоря уже о количестве постов по каждой категории. Поэтому нам нужно будет пройтись по результатам и подсчитать это самостоятельно.
$cat_array = array();
if ( $author_posts->have_posts() ) {
while ( $author_posts->have_posts() ) {
$author_posts->the_post();
$cat_array[] = wp_get_post_categories(get_the_ID(),array('fields'=>'names'));
}
}
Это дает массив $cat_array
, который просто содержит все названия категорий всех постов автора. Нам нужно будет посчитать дубликаты, чтобы увидеть, какая категория используется чаще всего. Есть функция PHP для этого: array_count_values
.
$cat_count = array_count_values($cat_array);
$cat_count = arsort($catcount); // сортирует массив по значению от высокого к низкому
В результате мы получаем $cat_count
, содержащий список категорий этого автора в порядке их убывания частоты. В зависимости от того, что вы хотите, вы можете использовать эту информацию, чтобы снова пройтись по $author_posts
или сделать новый запрос, чтобы получить все посты в трех лучших категориях:
$author="johndoe";
$top_cats = $cat_count[0] . ',' . $cat_count[1] . ',' . $cat_count[2];
$author_posts = new WP_Query (array (
'author' => $author,
'posts_per_page' =>-1,
'category_name' => $top_cats,
));
Учтите, что это довольно затратная процедура с точки зрения вычислений. Также обращаю внимание, что я не тестировал этот код, поэтому может потребоваться отладка.
Запишите эту функцию в ваш functions.php
или файл плагина-
function wpse_240422_get_author_post_categories( $author_id ) {
/**
* этот массив $categories будет содержать все категории постов, в которых автор публиковался
*/
$categories = array();
/**
* собираем все посты, опубликованные $author_id
*/
$posts = query_posts( array( 'author' => $author_id, 'posts_per_page' => -1 ) );
/**
* проходим по постам, берем их категории и сохраняем в массиве $categories
*/
foreach ( $posts as $post ) {
foreach ( get_the_category( $post->ID ) as $category ) {
$categories[] = $category->term_id;
}
}
/**
* теперь подсчитываем, сколько раз использовалась каждая категория
*/
$category_counter = array_count_values( $categories );
/**
* сортируем от высокого к низкому
*/
arsort( $category_counter );
return $category_counter;
}
Используйте:
Чтобы получить категории постов, использованные автором 1, просто передайте ID автора в эту функцию и возьмите только ключи. Например:
$author_categories = array_keys( wpse_240422_get_author_post_categories( 1 ) );
Теперь этот $author_categories
будет содержать все категории, в которых публиковался этот автор.
Наконец, используйте индексы массива, чтобы получить нужную вам категорию-
$most_1st = $author_categories[0]; // самая популярная категория
$most_2nd = $author_categories[1]; // вторая по популярности категория
$most_3rd = $author_categories[2]; // третья по популярности категория
Ответ или решение
Получение категорий пользователей с наибольшим количеством записей
В этом руководстве вы узнаете, как извлечь три категории с наибольшим количеством записей для каждого пользователя в WordPress. Мы начнем с SQL-запроса и затем перейдем к использованию функций PHP и WP_Query для динамического получения необходимой информации.
Проблема
На данный момент у вас есть запрос, который возвращает всех пользователей с категориями, однако вам нужны только первые три категории с наибольшим количеством записей для каждого пользователя.
Решение с использованием SQL
Для начала, ваш первоначальный SQL-запрос требует небольших изменений. Ваша цель – группировать результаты по пользователям и категориям, а затем ограничить результат тремя категориями с наибольшим количеством записей. Приведем пример, как можно структурировать такой запрос:
SELECT terms.term_id, terms.name, terms.slug, posts.post_author, COUNT(posts.ID) as post_count
FROM wp_posts as posts
JOIN wp_term_relationships as relationships ON posts.ID = relationships.object_ID
JOIN wp_term_taxonomy as tax ON relationships.term_taxonomy_id = tax.term_taxonomy_id
JOIN wp_terms as terms ON tax.term_id = terms.term_id
WHERE tax.taxonomy = "category"
AND posts.post_status = "publish"
AND posts.post_author IN (1, 2, 3)
GROUP BY posts.post_author, terms.term_id
ORDER BY posts.post_author, post_count DESC
Однако, это только основа. Дальше необходимо ограничить результат до трех категорий для каждого пользователя. Для этого мы можем воспользоваться оконными функциями, если ваша база данных поддерживает их. Например:
WITH RankedCategories AS (
SELECT
terms.term_id,
terms.name,
terms.slug,
posts.post_author,
COUNT(posts.ID) as post_count,
ROW_NUMBER() OVER (PARTITION BY posts.post_author ORDER BY COUNT(posts.ID) DESC) as rank
FROM wp_posts as posts
JOIN wp_term_relationships as relationships ON posts.ID = relationships.object_ID
JOIN wp_term_taxonomy as tax ON relationships.term_taxonomy_id = tax.term_taxonomy_id
JOIN wp_terms as terms ON tax.term_id = terms.term_id
WHERE tax.taxonomy = "category"
AND posts.post_status = "publish"
AND posts.post_author IN (1, 2, 3)
GROUP BY posts.post_author, terms.term_id
)
SELECT * FROM RankedCategories WHERE rank <= 3
Этот запрос сначала формирует список категорий для каждого автора, пронумеровывая их по количеству записей и затем фильтруя топ-3 для каждого автора.
Решение с использованием PHP и WP_Query
Если вы предпочитаете работу с результатами в PHP, вы можете использовать функции WordPress для получения категорий. Вот пример функции, которая возвращает три самых популярных категории для заданного автора:
function get_top_categories_by_author($author_id) {
// Массив для хранения категорий
$categories = [];
// Получаем все записи автора
$posts = get_posts(['author' => $author_id, 'posts_per_page' => -1]);
// Проходим по каждой записи и собираем категории
foreach ($posts as $post) {
$post_categories = get_the_category($post->ID);
foreach ($post_categories as $category) {
$categories[$category->term_id] = (isset($categories[$category->term_id]) ? $categories[$category->term_id] : 0) + 1;
}
}
// Сортируем массив по количеству записей
arsort($categories);
// Возвращаем только три самых популярных категории
return array_slice($categories, 0, 3, true);
}
// Пример использования для авторов 1, 2, 3
foreach ([1, 2, 3] as $author_id) {
$top_categories = get_top_categories_by_author($author_id);
// Дальше вы можете использовать $top_categories по вашему усмотрению
}
Заключение
Таким образом, вы можете использовать как SQL-запросы, так и функции PHP для получения трех категорий с наибольшим количеством записей для каждого пользователя. Использование оконных функций в SQL позволяет сделать это более эффективно, тогда как подход с PHP может быть более удобным для работы с данными после их экстракции. Выберите тот метод, который лучше подходит под вашу задачу и окружение.