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

Getting daily counts for events that don't happen every day

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

问题

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

例如求2015-07-01到2015-07-10每天的总注册人数

客户table 示例数据 [显示相关列]

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

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

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

不漂亮,但它给了你想要的。

here

创建带有日历的表并将其加入您的查询。

您正在寻找一种方法来列出所有日期,甚至是 customer table 中未显示的那些日期。这是 SQL 中众所周知的颈部疼痛。那是因为 SQL 的纯粹形式缺乏任何连续序列的概念......基数,天数,等等。

因此,您需要引入一个 table 包含连续基数、日期或其他内容的来源,然后将现有数据左联接到 table。

有几种方法可以做到这一点。一种是为自己创建一个 calendar table,在当前十年或本世纪或其他任何时间里的每一天都有一行,然后加入它。 (与现代数据库的功能相比,table 不会很大。

假设您有 table,并且它有一个名为 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 从日历 table 到您的数据集。如果您使用普通 JOIN,数据集中缺失的数据将抑制日历中的行。

其次,顶层 SELECT 中的 ISNULL 将数据集中缺失的空值转换为零值。

现在,你问,我在哪里可以得到那个日历 table?我恭敬地建议您查一下,如果您不明白,请再问一个问题。

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