钩子文档

posts_groupby

💡 云策文档标注

概述

posts_groupby 是一个 WordPress 过滤器,用于修改 WP_Query 查询中的 GROUP BY 子句。它主要用于处理涉及自定义字段或分类法查询时,对结果进行分组以避免重复行。

关键要点

  • posts_groupby 过滤器允许开发者自定义 GROUP BY 子句,参数包括 $groupby(当前 GROUP BY 字符串)和 $query(WP_Query 实例引用)。
  • 默认 GROUP BY 子句设置为 {$wpdb->posts}.ID,确保即使因多 meta 或多分类法查询产生多个结果,也能按帖子 ID 分组。
  • 此过滤器仅在查询包含自定义字段参数或分类法参数时生效,因为标准查询只返回帖子数据,无需 GROUP BY。

代码示例

add_filter( 'posts_groupby', 'my_posts_groupby' );

function my_posts_groupby($groupby) {
    global $wpdb;
    $groupby = "{$wpdb->posts}.ID";
    return $groupby;
}

注意事项

  • 使用此过滤器时需注意 MySQL 知识,因为 GROUP BY 通常需要配合 SELECT 语句修改,但 WordPress 查询默认不提供 SELECT 过滤器。
  • 在连接自定义表(如评分表)时,可通过 posts_join 过滤器加入,并使用 posts_groupby 确保每个帖子只返回一行,避免重复。

📄 原文内容

Filters the GROUP BY clause of the query.

Parameters

$groupbystring
The GROUP BY clause of the query.
$queryWP_Query
The WP_Query instance (passed by reference).

More Information

  • If you come with MySQL knowledge, the GROUP BY clause is pretty useless without the ability to modify the SELECT statement.
  • There is no SELECT filter since the query is supposed to return only the post data. The GROUP BY clause is set only when there are Custom Field Parameters for querying by post meta or Taxonomy Parameters for querying by taxonomy.
  • The default posts_groupby is set to {$wpdb->posts}.ID, which means that even if there are multiple results because of multiple meta and taxonomy, they are grouped together by the post id.

Source

$groupby = apply_filters_ref_array( 'posts_groupby', array( $groupby, &$this ) );

Changelog

Version Description
2.0.0 Introduced.

User Contributed Notes

  1. Skip to note 2 content

    Example migrated from Codex:

    add_filter( 'posts_groupby', 'my_posts_groupby' );
    
    function my_posts_groupby($groupby) {
        global $wpdb;
        $groupby = "{$wpdb->posts}.ID";
        return $groupby;
    }

    The code above will just set the GROUP BY clause whether or not, a taxonomy query or a meta query is present.

    For example, say we have a custom table (for ratings) and we wish to filter the posts using data from this table (only show posts that have a 5 star rating).

    We can use the posts_join filter to join the tables. If there are multiple entries in the ratings table, the join can return multiple results for the same post.

    We can make sure that we only have one row per post (that has all the entries for the ratings) by setting the GROUP BY clause. Remember that in the default query, GROUP BY clause is only set when there is a meta query or taxonomy query involved.