如何编写按日期接收数据组的查询?
Posted
技术标签:
【中文标题】如何编写按日期接收数据组的查询?【英文标题】:How write a query which receives data group by date? 【发布时间】:2018-02-20 15:26:29 【问题描述】:我写了一个简单的查询
SELECT date, count(user) as count FROM sessions GROUP BY date;
回复是这样的
但是,我想查看每个日期,如果日期不存在,行必须是这样的
2018-02-01 | 0
2018-02-02 | 0
2018-02-03 | 0
2018-02-04 | 0
2018-02-05 | 1503582
2018-02-06 | 0
2018-02-06 | 0
2018-02-08 | 5612270
...
...
...
2018-02-31 | 0
我应该如何重写我的查询以获取飞蛾中每天的数据?
【问题讨论】:
你有日期表吗? 有一个包含所有可能日期的日历帮助表。与该表右连接(!)。 @VamsiPrabhala,不,我没有日期表。我认为这不是解决此任务的正确方法 ***.com/questions/5635594/… @ArtemChernov - 日期表或数字表实际上是一种非常有用且有效的数据库结构。它使 SQL 更简单并且性能更高(更短的代码,更易于理解的代码,更简单的测试代码,改进的索引使用等)。这么快就放弃这样的想法将是一个错误,并且会损害您自己的职业发展。我强烈建议您在网上搜索有关数字表和/或日期表的各种做法。 【参考方案1】:您需要先生成一个日历并将其行与表session
到date
列连接起来。下面的子查询将根据@START_DATE
变量中设置的值生成所有 1 个月。
SET @START_DATE = '2018-01-01'; -- set your starting date here
SELECT a.`DATE`,
COUNT(b.user) AS `COUNT`
FROM
(
SELECT DATE(cal.date) `DATE`
FROM (
SELECT @START_DATE + INTERVAL xc DAY AS date
FROM (
SELECT @xi:=@xi+1 as xc from
(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc1,
(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc2,
(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc3,
(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc4,
(SELECT @xi:=-1) xc0
) xxc1
) cal
WHERE cal.date <= DATE_ADD(DATE_ADD(@START_DATE, INTERVAL 1 MONTH), INTERVAL -1 DAY)
) a
LEFT JOIN sessions b
ON a.`DATE` = b.`DATE`
GROUP BY a.`DATE`
ORDER BY a.`DATE`
这是Demo。
生成日期的子查询是从article: Generating a Series of Dates in mysql借来的,并稍作修改以允许用户输入开始日期。
【讨论】:
我同意这个原则,但我建议读者至少考虑创建一个具体化的数字表或日历表,而不是每次都派生一个。 @MatBailie 我同意你的说法。 这对我来说很难理解,但这项工作很完美 @artemchernov 它只是创建一个日期表并在其上左连接。至于日期表的计算方式,在链接中。拥有一个永久的日期表可以大大简化它。以上是关于如何编写按日期接收数据组的查询?的主要内容,如果未能解决你的问题,请参考以下文章
如何在最小和最大预算范围内编写接收有关一位制片人电影数据的请求