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

如何在PHP中通过SQL查询获取表数据及解决重复结果问题

解决SQL查询返回重复结果的问题

嘿,我来帮你排查这个重复结果的问题!你的核心问题出在表连接的方式上,咱们一步步拆解:

为什么会出现重复?

你用了SELECT * FROM yt_sub,done WHERE ...这种逗号分隔两个表的写法,这会触发SQL的笛卡尔积连接——简单说就是yt_sub里的每一行,都会和done里所有满足done.link != yt_sub.url AND done.uid != '$id'的行进行匹配。哪怕yt_sub里只有1条符合current < total的记录,只要done里有N条符合条件的行,这条记录就会被返回N次,最终结果自然充满重复。

修正后的查询写法

根据你的需求(从yt_sub选current < total的记录,且这些记录的url没有被uid != $id的用户在done表中标记过),推荐两种更合理的写法:

方法1:用NOT EXISTS子查询(可读性高)

SELECT DISTINCT yt_sub.* 
FROM yt_sub
WHERE yt_sub.current < yt_sub.total
AND NOT EXISTS (
    SELECT 1 FROM done 
    WHERE done.link = yt_sub.url 
    AND done.uid != '$id'
)
ORDER BY RAND() 
LIMIT 12;

这里的NOT EXISTS会检查:当前yt_sub的url是否没有出现在done表中uid != $id的link字段里,完全符合你的逻辑。加上DISTINCT是双重保险,避免yt_sub自身有重复行的情况。

方法2:用LEFT JOIN + IS NULL(性能友好)

SELECT DISTINCT yt_sub.* 
FROM yt_sub
LEFT JOIN done ON done.link = yt_sub.url AND done.uid != '$id'
WHERE yt_sub.current < yt_sub.total
AND done.link IS NULL
ORDER BY RAND() 
LIMIT 12;

这种写法是把yt_sub和done做左连接,然后只保留那些在done中没有匹配到的yt_sub行,效果和上面的方法一致,部分数据库对这种写法的优化更好。

额外提醒:避免SQL注入

你直接把$id拼进SQL语句里有安全风险,如果你用的是CodeIgniter框架(从$this->db->query的写法看大概率是),建议用参数绑定的方式:

$query = $this->db->query(
    "SELECT DISTINCT yt_sub.* FROM yt_sub WHERE yt_sub.current < yt_sub.total AND NOT EXISTS (SELECT 1 FROM done WHERE done.link = yt_sub.url AND done.uid != ?) ORDER BY RAND() LIMIT 12",
    [$id]
);

这样框架会自动处理参数转义,防止SQL注入攻击。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:24:25