1

我有一个跟踪已发送电子邮件的表格。这很简单。

身份证 | 日期时间 | 电子邮件 | 主题 | 信息

几年来我一直在收集数据。有些日子我在表中没有任何条目。

查询1:

SELECT COUNT(ID) FROM emails
WHERE DATE(datetime) >= 'XXXX-XX-XX'
AND DATE(datetime) is <= 'ZZZZ-ZZ-ZZ'
GROUP BY DATE(datetime)

然后我使用一些 php 提前一年获取 XXXX 和 YYYY 并运行与第一个相同的第二个查询......

查询2:

SELECT COUNT(ID) from emails
WHERE DATE(datetime) >= 'XXXX-XX-XX'
AND DATE(datetime) is <= 'ZZZZ-ZZ-ZZ'
GROUP BY DATE(datetime)

我正在使用图表包来比较我在某个日期范围内收到了多少封电子邮件,然后我叠加了一年前在同一范围内收到多少封电子邮件。这是现在的两个查询,我将结果绘制成图表。

问题是 mysql 在 2011 年的某一天没有任何电子邮件,但在 2012 年的同一天有几封电子邮件。

组合结果并将它们绘制成图表会使结果产生偏差,因为我错过了那一天的去年日期和 0 值,有效地使我的所有值不再匹配。

2011-03-01 10    2012-03-01 4
2011-03-02 4     2012-03-02 2
2011-03-03 6     2012-03-04 1  <---- see where the two queries
                               end up diverging? (I had nothing
                               logged for 2012-03-03 so naturally
                               it was not in the results.

有没有一种方法可以让 mysql 输出我需要的数据,包括值出现在一年中但不是另一个的日期,或者如果任何一年都没有出现值(仍然需要日期和 0)所以我的图表有效?

我似乎无法弄清楚如何做到这一点......

谢谢!

4

1 回答 1

2

有几种不同的方法可以获取一组连续日期的结果。我最喜欢的是使用虚拟表或来自 AI PK 的现有连续 ID 集创建所需的完整集。像这样的东西-

SELECT '2011-01-01' + INTERVAL (id -1) DAY
FROM dummy
WHERE id BETWEEN 1 AND 365

这将返回 2011 年的完整天数,然后可以将其 LEFT JOINed 到您的电子邮件表中以获取计数 -

SELECT `dates`.`date`, COUNT(emails.id)
FROM (
    SELECT '2011-01-01' + INTERVAL (id - 1) DAY AS `date`, '2011-01-01 23:59:59' + INTERVAL (id - 1) DAY AS `end_of_day`
    FROM dummy
    WHERE id BETWEEN 1 AND 365
) `dates`
LEFT JOIN emails
    ON `emails`.`datetime` BETWEEN `dates`.`date` AND `dates`.`end_of_day`
GROUP BY `dates`.`date`

要填充您的虚拟/序列表,您可以手动插入前十个值,然后使用 INSERT ... SELECT 添加其余的 -

CREATE TABLE dummy (id INTEGER NOT NULL PRIMARY KEY);
INSERT INTO dummy VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
SET @tmp := (SELECT MAX(id) FROM dummy) + 1;
INSERT INTO dummy
SELECT @tmp + id
FROM dummy;

您需要在每次运行 INSERT ... SELECT 查询之前执行 SET 查询。

于 2012-04-14T19:39:22.727 回答