如何修复这个内连接 SQL 查询?而不是 1 count() 返回 3

Posted

技术标签:

【中文标题】如何修复这个内连接 SQL 查询?而不是 1 count() 返回 3【英文标题】:How to fix this inner join SQL query? instead of 1 count() is returning 3 【发布时间】:2021-04-19 13:28:10 【问题描述】:

我正在尝试从两个表中获取过去 7 天的数据,但是我有一点错误。

我的初始查询是这样的:

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(c.id) AS cards, count(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

我得到了这个结果:

问题是 mymyv_cards 不正确,因为我只有一条记录。

如果我执行这个查询:

      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(mc.id) AS mymyv_cards
      from dates d 
      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

我得到了正确的结果:

我不知道为什么会这样,我不确定这是不是因为 inner join

【问题讨论】:

请分享更多详细信息,例如表结构、示例输入数据以及与该输入数据对应的预期输出。另外,请分享您解决问题的尝试 【参考方案1】:

没有样本数据,很难确定问题所在。我认为 dates d inner join cards c 导致了这种情况。这是一个有效的结果。在卡片表中可能有三行日期表中的一行。因此,当您使用先前连接的结果加入 mymyv_cards 时,mymyv_cards 表中的单行将获得三行。

您只能使用 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

【讨论】:

你是对的,这就是问题所在,使用 distinct 我可以修复错误。谢谢!

以上是关于如何修复这个内连接 SQL 查询?而不是 1 count() 返回 3的主要内容,如果未能解决你的问题,请参考以下文章

默认情况下,条件使用“内连接”而不是“左连接”方法使我的查询工作不是我计划的方式

如何优化这个 sql 查询(内连接)

在 MySQL 中,如何编写 SQL 来连接两个表而不是一个子查询?

如何使用 sql 查询而不是 api 覆盖列

SQL查询,外连接,cte?需要使用“左”值修复运行总计

如何将带有内连接语句的 Sql 查询转换为带有 Where 语句的 sql 查询(语句中没有内连接)