2017-08-05 91 views
0

我的以下查询显示每天(最近2天)发现的电子邮件的日期和计数显示所有日期,即使是在mySQL中的数据为零的日期?

我的问题是,如果今天没有找到电子邮件,则今天的日期将不会显示在输出中。 (如果昨天有电子邮件,它会显示昨天的日期和电子邮件只有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 
+2

考虑在应用程序代码 – Strawberry

+0

处理数据显示的问题(如丢失的日期问题)只有你想要今天和昨天的电子邮件计数? –

+0

@PaulSpiegel是的。但即使电子邮件表中没有行,或没有满足查询的行,输出必须有今天和昨天为0 – EnexoOnoma

回答

0

创建日期列表有许多技巧(或类似的数字序列)。我喜欢与MySQL一起使用的是使用@sqlvariables。我通常会从基线值开始,例如您的日期为-2天。我将对数据库中的任何其他表进行交叉连接,这些表至少具有与您的输出一样多的记录数......说30天或全年366天或更长时间。内部的SQL变量准备将不断增加自己的增量(你甚至可以做日期范围,如开始/结束一周,月等)。现在你有你想要填写的所有可能日期的表格。

现在,我通过值进行辅助查询 - 在这种情况下,您的电子邮件日期和应用组。在此查询中使用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 

现在,通过查询来判断,但是未澄清的请求......你的邮件表可以有将来的日期?那是对的吗?如博士办公室和约会是为未来,你想收到一个给定的范围内的电子邮件。这就是我所推断的,因此我的限制只能在30天内出去......如果您需要更长的时间,只需扩展LIMIT子句即可。

+0

嗨,感谢您的这一点,它的工作原理。但是,我不明白为什么表格必须至少有行。有时候,电子邮件表格会有0行。 – EnexoOnoma

+0

在表中有零的情况下,它不返回任何结果,但是必须始终拥有今天和昨天的日期,即使使用0 – EnexoOnoma

+0

使用电子邮件表的例子就是......“AnyTableWithAtLeast3RecordInIt “可以是数据库中的任意一个表,它至少有你需要的记录数量。 – DRapp

0

您需要一个包含所需范围内所有日期的表格。如果仅仅是今天和昨天,你可以很容易地创建它作为一个子查询(派生表)。

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 
相关问题