获取并非每天发生的事件的每日计数
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/
我有一个 客户 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/