【问题标题】:Show all dates even those with zero data in it in mySQL?在 mySQL 中显示所有日期,即使是那些数据为零的日期?
【发布时间】:2017-08-05 14:32:37
【问题描述】:

我的以下查询显示每天(过去 2 天)找到的电子邮件的日期和数量

我的问题是,如果今天没有找到电子邮件,今天的日期将不会显示在输出中。 (如果昨天有电子邮件,它只会显示 1 行昨天的日期和电子邮件)。

如何编辑我的查询以始终显示 2 行,今天和昨天,电子邮件的日期和数量甚至为零?

SELECT maildate, 
       COUNT(*) AS totalEmails 
FROM   emails 
WHERE  maildate >= Date_add(Curdate(), interval - 2 DAY) 
       AND company_id = 1 
GROUP  BY DATE(maildate) 
ORDER  BY maildate desc 

【问题讨论】:

  • 考虑在应用程序代码中处理数据显示问题(如缺少日期问题)
  • 您只需要今天和昨天的电子邮件计数吗?
  • @PaulSpiegel 是的。但是即使 emails 表中没有行,或者没有满足查询的行,输出的今天和昨天也必须为 0

标签: php mysql


【解决方案1】:

创建日期列表(或类似的数字序列)有很多技巧。我喜欢与 MySQL 一起使用的一个是使用 @sqlvariables。我通常会从基线值开始,例如您的日期 -2 天。我将对数据库中的任何其他表进行交叉连接,该表的记录至少与您在输出中所期望的一样多......比如说 30 天,或者一整年 366 天,或者更长。内部 sql 变量 prep 将通过任何增量不断增加自身(您甚至可以执行日期范围,例如一周的开始/结束、月份等)。现在你已经有了你想要填写的所有可能日期的表格。

现在,我按值进行二次查询——在本例中是您的电子邮件日期并应用分组依据。在此查询中使用 where 子句将使 IT 更快,因为它可以在将 LEFT-JOIN 返回到日期范围结果集之前利用其查询结果集上的日期。

现在,您的简单左​​连接将包含所有日期的两个部分以及那些确实存在的相应计数。

请注意,“JustDates”查询中的表别名“AnyTableWithAtLeast3RecordInIt”实际上可能是您的“电子邮件”表。由于我们不关心除了记录之外的任何标准,并且在我的示例中我们应用了 30 天的限制,这将是即时的。

select 
      JustDates.DateToInclude,
      coalesce( SumCnts.TotalEmails, 0 ) TotalEmails
   from
      ( select
              @myDate := DATE_ADD( @myDate, INTERVAL 1 DAY ) as DateToInclude
           from
              ( select @myDate := Date_add(Curdate(), interval - 2 DAY) ) as SQLVars,
              AnyTableWithAtLeast3RecordInIt
           limit 30 ) JustDates
      left join 
      ( select
              maildate, 
              COUNT(*) AS totalEmails 
           FROM 
              emails 
           WHERE  
                  maildate >= Date_add(Curdate(), interval - 2 DAY) 
              AND company_id = 1 
           GROUP BY 
              DATE(maildate) ) SumCnts
         ON JustDates.DateToInclude = SumCnts.MailDate

现在,从您的查询来看,但未澄清的请求...您的电子邮件表可以有未来的日期吗?那是对的吗?例如 Dr. Office 和约会是为未来而设的,您希望在给定范围内发送电子邮件。这就是我所推断的,因此我的限制只能使用 30 天……如果您需要更长的时间,只需延长 LIMIT 子句。

【讨论】:

  • 您好,谢谢您,它有效。但是,我真的不明白为什么表必须至少有行。有时电子邮件表中会有 0 行。
  • 如果表中有零,它不会返回任何结果,但必须始终有今天和昨天的日期,即使是 0
  • 使用 emails 表的示例只是......“AnyTableWithAtLeast3RecordInIt”可以是您数据库中的任何表,至少包含您需要的记录数。
【解决方案2】:

您需要一个包含所需范围内所有日期的表格。如果它只是关于今天和昨天,您可以轻松地将其创建为子查询(派生表)。

SELECT Curdate() as maildate
UNION ALL
SELECT Curdate() - INTERVAL 1 DAY

http://rextester.com/ALH50651

现在您可以 LEFT JOIN 表并计算行数:

SELECT sub.maildate, 
       COUNT(m.maildate) AS totalEmails
FROM (
    SELECT Curdate() as maildate
    UNION ALL
    SELECT Curdate() - INTERVAL 1 DAY
) sub
LEFT JOIN emails m 
  ON  DATE(m.maildate) = sub.maildate
  AND m.company_id = 1 
GROUP BY sub.maildate
ORDER BY sub.maildate desc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多