获取每天不发生的事件的每日计数

时间:2016-03-19 20:17:34

标签: mysql datetime aggregate-functions

我有一个客户表,当客户注册时会插入新行。

问题

我想知道给定日期范围内每天注册的总次数。

例如,查找从2015-07-01到2015-07-10每天注册的总数

客户表 样本数据[显示相关列]

customerid    username    created
1             mrbean      2015-06-01
2             tom         2015-07-01
3             jerry       2015-07-01
4             bond        2015-07-02
5             superman    2015-07-10
6             tintin      2015-08-01
7             batman      2015-08-01
8             joker       2015-08-01

所需输出

created      signup
2015-07-01   2
2015-07-02   1
2015-07-03   0
2015-07-04   0
2015-07-05   0
2015-07-06   0
2015-07-07   0
2015-07-08   0
2015-07-09   0
2015-07-10   1

使用了查询

SELECT 
    DATE(created) AS created, COUNT(1) AS signup
FROM
    customer
WHERE
    DATE(created) BETWEEN '2015-07-01' AND '2015-07-10'
GROUP BY DATE(created)
ORDER BY DATE(created)

我得到以下输出:

created      signup
2015-07-01   2
2015-07-02   1
2015-07-10   1

我应该在查询中进行哪些修改才能获得所需的输出?

3 个答案:

答案 0 :(得分:2)

您正在寻找一种方法来获取列出的所有日期,即使是onChange: function (option, checked, select) { try{ if (checked == true) { var t0 = performance.now(); $('#Cities').multiselect('select', Object.keys(CountryCitySite[$(option).text()]),'triggeronChange'); var t1 = performance.now(); list = Object.keys(CountryCitySite[$(option).text()]) var t2 = performance.now(); for(var i = 0; i<list.length; i++) { $('#Sites').multiselect('select', CitySite[list[i]]) } var t3 = performance.now(); } else if (checked == false) { $('#Cities').multiselect('deselect', Object.keys(CountryCitySite[$(option).text()]), 'triggeronChange'); list = Object.keys(CountryCitySite[$(option).text()]) for(var i = 0; i<list.length; i++) { $('#Sites').multiselect('deselect', CitySite[list[i]], 'triggeronChange') } } } 表中未显示的日期。这是SQL中的臭名昭着的痛苦。那是因为在纯粹的形式中,SQL缺乏连续的任何序列的概念......基数,天,等等。

因此,您需要引入一个包含连续基数,日期或其他内容的表,然后将现有数据LEFT JOIN加入该表。

有几种方法可以做到这一点。一个是创建一个customer表,在当前十年或者世纪或者其他任何一天都有一行,然后加入它。 (与现代数据库的功能相比,该表不会很大。

假设您拥有该表,并且它有一个名为calendar的列。那你就做了。

date

注意几件事。首先,从日历表到您的数据集的 SELECT calendar.date AS created, ISNULL(a.customer_count, 0) AS customer_count FROM calendar LEFT JOIN ( SELECT COUNT(*) AS customer_count, DATE(created) AS created FROM customer GROUP BY DATE(created) ) a ON calendar.date = a.created WHERE calendar.date BETWEEN start AND finish ORDER BY calendar.date 。如果您使用普通LEFT JOIN,数据集中缺少的数据将禁止日历中的行。

其次,toplevel JOIN中的ISNULL可将数据集中缺失的null值变为零值。

现在,您问,我在哪里可以获得该日历表?我恭敬地建议你仔细查看,如果你无法弄明白,可以提出另一个问题。

我写了一篇关于此的文章,你可以在这里找到。http://www.plumislandmedia.net/mysql/filling-missing-data-sequences-cardinal-integers/

答案 1 :(得分:1)

here

使用日历创建teble并将其加入您的查询中。

答案 2 :(得分:0)

DECLARE @MinDate DATE = '2015-07-01',
        @MaxDate DATE = '2015-07-10';

Create Table tblTempDates 
(created date, signup int)

insert into tblTempDates
SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
        Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate),  0 As Signup
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b;

Create Table tblTempQueryDates
(created date, signup int)

INSERT INTO tblTempQueryDates
SELECT 
    created AS created, COUNT(scandate) AS signup
FROM
    customer
WHERE
    created BETWEEN @MinDate AND @MaxDate
GROUP BY created

UPDATE    tblTempDates
SET  tblTempDates.signup = tblTempQueryDates.signup            
FROM         tblTempDates INNER JOIN
                      tblTempQueryDates ON tblTempDates.created = tblTempQueryDates.created

select * from tblTempDates
order by created

Drop Table tblTempDates
Drop Table tblTempQueryDates

不漂亮,但它可以满足您的需求。