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

PHP/MySQL环境下动态SQL查询实现跨来源新闻随机展示逻辑咨询

跨新闻来源打散展示实现方案

以下实现基于PHP+MySQL技术栈,可完全避免同站点内容连续展示的问题:

方案1:纯SQL实现(适合数据量较小、使用MySQL8.0+的场景)

核心思路是通过窗口函数给同站点新闻打上行号标记,再按行号跨站点随机排序:

WITH ranked_news AS (
    SELECT 
        id, title, site, publish_date,
        -- 同站点内的新闻先随机排序分配行号
        ROW_NUMBER() OVER (PARTITION BY site ORDER BY RAND()) AS site_row_num
    FROM news
    WHERE publish_date = CURDATE() -- 筛选当天新闻
)
SELECT id, title, site
FROM ranked_news
-- 先按行号聚合,同行号的不同站点内容再随机打乱
ORDER BY site_row_num, RAND();

注:如果某个站点的新闻数量比其余所有站点的总数量还多,极端情况下末尾会出现少量连续同站点内容,属于正常可接受范围

方案2:PHP+SQL组合实现(兼容低版本MySQL、打散效果更灵活)

适合数据量较大、需要自定义排序规则的场景,分两步实现:

  • 第一步:从数据库拉取当日所有新闻,按站点分组并分别打乱
// 拉取当日全量新闻
$allNews = $pdo->query("SELECT id, title, site FROM news WHERE publish_date = CURDATE()")->fetchAll(PDO::FETCH_ASSOC);
// 按站点分组
$siteGroup = [];
foreach ($allNews as $item) {
    $siteGroup[$item['site']][] = $item;
}
// 每个站点内部的新闻先打乱顺序
foreach ($siteGroup as &$newsList) {
    shuffle($newsList);
}
  • 第二步:轮转拉取各站点内容生成最终列表
$finalList = [];
do {
    $hasRemain = false;
    // 每次拉取前打乱站点顺序,避免站点展示顺序固定
    $siteKeys = array_keys($siteGroup);
    shuffle($siteKeys);
    foreach ($siteKeys as $site) {
        if (!empty($siteGroup[$site])) {
            $finalList[] = array_shift($siteGroup[$site]);
            $hasRemain = true;
        }
    }
} while ($hasRemain);

最终得到的$finalList就是打散后的新闻列表,不会出现同站点内容连续的情况。

性能优化建议

如果每日新闻量级超过1万条,可在爬虫导入新闻时新增shuffle_rank字段,给同站点的新闻随机分配1~N的整数排名,后续查询直接按shuffle_rank排序即可,不需要每次请求都计算随机数,可大幅降低接口耗时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:15:07