Получить категории пользователей с наибольшим количеством постов в них.

Вопрос или проблема

Я пытаюсь сделать запрос, чтобы получить первые 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 может быть более удобным для работы с данными после их экстракции. Выберите тот метод, который лучше подходит под вашу задачу и окружение.

Оцените материал
Добавить комментарий

Капча загружается...