You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于post__in和p数组让查询结果重复显示指定文章?

保留post__in中的重复文章结果

这个需求确实有点反常规(毕竟大部分人都在想办法去重😂),不过核心问题在于WordPress的WP_Query默认会利用数据库的IN子句查询post__in,而数据库的IN本身只会返回唯一的ID结果,不管你在数组里写多少次重复值。要绕过这个限制,我们可以通过修改查询语句的方式,让数据库返回重复的行,而且不用额外遍历数组。

解决方案:使用posts_clauses过滤器修改SQL查询

我们可以通过WordPress的posts_clauses钩子,把原来的IN查询改成JOIN一个包含重复ID的临时数据集,这样每个重复的ID都会对应一条查询结果,同时还能保留你传入数组的顺序。

具体代码实现

首先添加过滤器函数:

add_filter('posts_clauses', 'preserve_duplicate_posts_in_query', 10, 2);
function preserve_duplicate_posts_in_query($clauses, $query) {
    // 只处理包含post__in参数的主查询(可根据需求调整范围)
    if (!$query->is_main_query() || empty($query->query_vars['post__in'])) {
        return $clauses;
    }

    $post_ids = $query->query_vars['post__in'];
    // 如果数组没有重复值,直接返回原查询
    if (count($post_ids) === count(array_unique($post_ids))) {
        return $clauses;
    }

    // 生成带排序序号的临时数据集(保证结果顺序和传入数组一致)
    $temp_table_rows = [];
    $sort_order = 0;
    foreach ($post_ids as $id) {
        $sort_order++;
        $temp_table_rows[] = "(SELECT " . (int)$id . " AS post_id, {$sort_order} AS sort_order)";
    }
    $temp_table = implode(' UNION ALL ', $temp_table_rows);

    // 修改FROM子句,JOIN临时表
    $clauses['from'] = "{$clauses['from']} JOIN ({$temp_table}) AS ordered_posts ON wp_posts.ID = ordered_posts.post_id";
    // 移除原查询中的ID IN条件
    $clauses['where'] = preg_replace('/\bAND?\s+ID\s+IN\s*\([^)]+\)/i', '', $clauses['where']);
    // 按照临时表的序号排序,保持传入数组的顺序
    $clauses['orderby'] = "ordered_posts.sort_order ASC";
    // 确保不添加DISTINCT去重
    $clauses['distinct'] = '';

    return $clauses;
}

然后正常使用WP_Query即可:

// 传入包含重复ID的数组
$args = [
    'post_type' => 'post',
    'post__in' => [123, 456, 123, 789], // 这里有重复的123
    'posts_per_page' => -1, // 显示所有匹配结果
];
$query = new WP_Query($args);

// 循环输出结果,你会看到123对应的文章出现两次
if ($query->have_posts()) {
    while ($query->have_posts()) {
        $query->the_post();
        echo get_the_title() . '<br>';
    }
    wp_reset_postdata();
}

为什么这个方法高效?

  • 只需要一次数据库查询就能得到包含重复值的结果集,不需要额外遍历数组去逐个获取文章;
  • 利用数据库的JOIN操作,性能上比PHP层面循环get_post()要高很多,尤其是当数组较大时;
  • 完美保留了你传入数组的顺序,不需要额外处理排序。

内容的提问来源于stack exchange,提问作者user137681

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:46:36