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

如何修复SQL左连接查询中count()返回3而非预期1的问题?

问题原因与解决方案

你踩的这个坑我之前也掉进去过!核心问题出在同时对两张表做LEFT JOIN会产生笛卡尔积,直接导致计数被错误放大。

为什么会出现计数异常?

当你把dates表同时和cards、mymyv_cards做LEFT JOIN时,假设某天cards有3条符合条件的记录,mymyv_cards有1条符合条件的记录,两者关联后会生成3×1=3条重复的行数据。这时候count(mc.id)会把这3行都统计进去,所以结果显示为3,而不是实际的1条。而单独查询mymyv_cards时,因为没有和另一张表关联,不会产生这种重复行,所以计数正确。

两种可行的解决方案

方案1:先分别统计每张表的日数据,再关联日期表(推荐)

这种方式先对两张表按天聚合统计,避免了笛卡尔积的问题,性能也更优:

with recursive dates as (
 select curdate() as dte, 1 as lev
 union all
 select dte - interval 1 day, lev + 1
 from dates where lev < 7
),
cards_daily as (
    select 
        str_to_date(left(publication_date, 10), '%d-%m-%Y') as stat_date,
        count(id) as cards_count
    from cards
    where publicated = 1
    group by stat_date
),
mymyv_cards_daily as (
    select 
        str_to_date(left(publication_date, 10), '%d-%m-%Y') as stat_date,
        count(id) as mymyv_count
    from mymyv_cards
    where publicated = 1
    group by stat_date
)
select 
    DATE_FORMAT(d.dte, '%d') AS date,
    coalesce(c.cards_count, 0) AS cards, -- 用coalesce处理无数据的日期,显示0而非null
    coalesce(m.mymyv_count, 0) AS mymyv_cards
from dates d
left join cards_daily c on c.stat_date = d.dte
left join mymyv_cards_daily m on m.stat_date = d.dte
group by d.dte;

方案2:使用count(distinct)临时修正(适合快速验证)

如果只是想快速验证结果,可以给count加上distinct关键字,强制统计唯一的id:

with recursive dates as (
 select curdate() as dte, 1 as lev
 union all
 select dte - interval 1 day, lev + 1
 from dates where lev < 7
)
select 
    DATE_FORMAT(d.dte, '%d') AS date, 
    count(distinct c.id) AS cards, 
    count(distinct mc.id) AS mymyv_cards
from dates d
left join cards c on c.publicated = 1 and str_to_date(left(c.publication_date, 10), '%d-%m-%Y') >= d.dte and str_to_date(left(c.publication_date, 10), '%d-%m-%Y') < d.dte + interval 1 DAY
left join mymyv_cards mc on mc.publicated = 1 and str_to_date(left(mc.publication_date, 10), '%d-%m-%Y') >= d.dte and str_to_date(left(mc.publication_date, 10), '%d-%m-%Y') < d.dte + interval 1 day
group by d.dte;

不过这种方式本质上还是会产生笛卡尔积,只是通过去重修正了计数,数据量大时性能会受影响,所以更推荐方案1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 14:39:09