获取每周在 SQL 中创建的记录数
Get a count of records created each week in SQL
我有一个table问题。我如何统计一周内提出的所有问题?
更一般地说,我如何按创建记录的周对记录进行分类?
Questions
id created_at title
----------------------------------------------------
1 2014-12-31 09:43:42 "Add things"
2 2013-11-23 02:98:55 "How do I ruby?"
3 2015-01-15 15:11:19 "How do I python?"
...
我正在使用 SQLLite,但 PG 答案也很好。
或者,如果您使用 Rails ActiveRecord 得到答案,那就太棒了,但不是必需的。
我一直在尝试使用 DATEPART() 但还没有成功:http://msdn.microsoft.com/en-us/library/ms174420.aspx
使用 strfdate(%V)
获取周数
将其存储在数据库中,并使用它来确定问题是在哪一周提出的
http://apidock.com/ruby/DateTime/strftime
SQL 也可以使用 DATE_FORMAT(datetime,'%u')
所以使用:
SELECT DATE_FORMAT(column,'%u') FROM Table
SQLite 没有像 MS SQL Server 那样的本机日期时间类型,因此答案可能取决于您存储日期的方式。并非所有 T-SQL 都适用于 SQLite。
您可以将日期时间存储为从 1/1/1970 12:00 AM 开始计算秒数的整数。一周有 604,800 秒。所以你可以查询像
这样的表达式
rawdatetime / 604800 -- iff rawdatetime is integer
更多关于在 SQL 网站上处理日期时间的信息:https://www.sqlite.org/datatype3.html
如果 created_at
字段已经被索引,我会简单地查找 X 和 Y 之间具有 created_at
值的所有行。这样就可以使用索引。
例如,要获取 2015 年第 3 周具有 created_at
值的行,您需要 运行:
select *
from questions
where created_at between '2015-01-11' and '2015-01-17'
这将允许使用索引。
如果您希望能够在 where 子句中指定一个星期,您可以使用 date_part
或 extract
函数向此 table 添加一列来存储年份和 week #,然后索引该列以便查询可以利用它。
如果您不想添加该列,您当然可以在 where 子句中使用任一函数并针对 table 进行查询,但您将无法利用任何索引.
因为您提到不想向 table 添加列,我建议添加基于函数的索引。
例如,如果您的 ddl 是:
create table questions
(
id int,
created_at timestamp,
title varchar(20)
);
insert into questions values
(1, '2014-12-31 09:43:42','"Add things"'),
(2, '2013-11-23 02:48:55','"How do I ruby?"'),
(3, '2015-01-15 15:11:19','"How do I python?"');
create or replace function to_week(ts timestamp)
returns text
as 'select concat(extract(year from ts),extract(week from ts))'
language sql
immutable
returns null on null input;
create index week_idx on questions (to_week(created_at));
你可以运行:
select q.*, to_week(created_at) as week
from questions q
where to_week(created_at) = '20153';
并得到:
| ID | CREATED_AT | TITLE | WEEK |
|----|--------------------------------|--------------------|-------|
| 3 | January, 15 2015 15:11:19+0000 | "How do I python?" | 20153 |
(反映 2015 年的第三周,即 '20153'
)
Fiddle: http://sqlfiddle.com/#!15/c77cd/3/0
你也可以 运行:
select q.*,
concat(extract(year from created_at), extract(week from created_at)) as week
from questions q
where concat(extract(year from created_at), extract(week from created_at)) =
'20153';
Fiddle: http://sqlfiddle.com/#!15/18c1e/3/0
但是它不会利用基于函数的索引,因为有none。此外,它不会使用您在 created_at
字段上可能拥有的任何索引,因为虽然该字段可能已被索引,但您实际上并没有在该字段上进行搜索。您正在搜索针对该字段应用的函数的结果。所以不能使用列本身的索引。
如果 table 很大,您将需要一个基于函数的索引或一个包含该周的列,该列本身已被索引。
在 postgreSQL 中很简单,如下所示:
SELECT id, created_at, title, date_trunc('week', created_at) created_week
FROM Questions
如果您想获得每周的问题数,只需执行以下操作:
SELECT date_trunc('week', created_at) created_week, COUNT(*) weekly_cnt
FROM Questions
GROUP BY date_trunc('week', created_at)
希望这对您有所帮助。请注意,date_trunc()
将 return 一个日期而不是一个数字(即,它不会 return 一年中的第几周的序数)。
更新:
此外,如果您想在单个查询中完成这两项操作,您可以按如下方式进行:
SELECT id, created_at, title, date_trunc('week', created_at) created_week
, COUNT(*) OVER ( PARTITION BY date_trunc('week', created_at) ) weekly_cnt
FROM Questions
在上面的查询中,我将 COUNT(*)
用作 window 函数并按创建问题的周进行分区。
我有一个table问题。我如何统计一周内提出的所有问题?
更一般地说,我如何按创建记录的周对记录进行分类?
Questions
id created_at title
----------------------------------------------------
1 2014-12-31 09:43:42 "Add things"
2 2013-11-23 02:98:55 "How do I ruby?"
3 2015-01-15 15:11:19 "How do I python?"
...
我正在使用 SQLLite,但 PG 答案也很好。
或者,如果您使用 Rails ActiveRecord 得到答案,那就太棒了,但不是必需的。
我一直在尝试使用 DATEPART() 但还没有成功:http://msdn.microsoft.com/en-us/library/ms174420.aspx
使用 strfdate(%V)
获取周数
将其存储在数据库中,并使用它来确定问题是在哪一周提出的
http://apidock.com/ruby/DateTime/strftime
SQL 也可以使用 DATE_FORMAT(datetime,'%u')
所以使用:
SELECT DATE_FORMAT(column,'%u') FROM Table
SQLite 没有像 MS SQL Server 那样的本机日期时间类型,因此答案可能取决于您存储日期的方式。并非所有 T-SQL 都适用于 SQLite。
您可以将日期时间存储为从 1/1/1970 12:00 AM 开始计算秒数的整数。一周有 604,800 秒。所以你可以查询像
这样的表达式rawdatetime / 604800 -- iff rawdatetime is integer
更多关于在 SQL 网站上处理日期时间的信息:https://www.sqlite.org/datatype3.html
如果 created_at
字段已经被索引,我会简单地查找 X 和 Y 之间具有 created_at
值的所有行。这样就可以使用索引。
例如,要获取 2015 年第 3 周具有 created_at
值的行,您需要 运行:
select *
from questions
where created_at between '2015-01-11' and '2015-01-17'
这将允许使用索引。
如果您希望能够在 where 子句中指定一个星期,您可以使用 date_part
或 extract
函数向此 table 添加一列来存储年份和 week #,然后索引该列以便查询可以利用它。
如果您不想添加该列,您当然可以在 where 子句中使用任一函数并针对 table 进行查询,但您将无法利用任何索引.
因为您提到不想向 table 添加列,我建议添加基于函数的索引。
例如,如果您的 ddl 是:
create table questions
(
id int,
created_at timestamp,
title varchar(20)
);
insert into questions values
(1, '2014-12-31 09:43:42','"Add things"'),
(2, '2013-11-23 02:48:55','"How do I ruby?"'),
(3, '2015-01-15 15:11:19','"How do I python?"');
create or replace function to_week(ts timestamp)
returns text
as 'select concat(extract(year from ts),extract(week from ts))'
language sql
immutable
returns null on null input;
create index week_idx on questions (to_week(created_at));
你可以运行:
select q.*, to_week(created_at) as week
from questions q
where to_week(created_at) = '20153';
并得到:
| ID | CREATED_AT | TITLE | WEEK |
|----|--------------------------------|--------------------|-------|
| 3 | January, 15 2015 15:11:19+0000 | "How do I python?" | 20153 |
(反映 2015 年的第三周,即 '20153'
)
Fiddle: http://sqlfiddle.com/#!15/c77cd/3/0
你也可以 运行:
select q.*,
concat(extract(year from created_at), extract(week from created_at)) as week
from questions q
where concat(extract(year from created_at), extract(week from created_at)) =
'20153';
Fiddle: http://sqlfiddle.com/#!15/18c1e/3/0
但是它不会利用基于函数的索引,因为有none。此外,它不会使用您在 created_at
字段上可能拥有的任何索引,因为虽然该字段可能已被索引,但您实际上并没有在该字段上进行搜索。您正在搜索针对该字段应用的函数的结果。所以不能使用列本身的索引。
如果 table 很大,您将需要一个基于函数的索引或一个包含该周的列,该列本身已被索引。
在 postgreSQL 中很简单,如下所示:
SELECT id, created_at, title, date_trunc('week', created_at) created_week
FROM Questions
如果您想获得每周的问题数,只需执行以下操作:
SELECT date_trunc('week', created_at) created_week, COUNT(*) weekly_cnt
FROM Questions
GROUP BY date_trunc('week', created_at)
希望这对您有所帮助。请注意,date_trunc()
将 return 一个日期而不是一个数字(即,它不会 return 一年中的第几周的序数)。
更新:
此外,如果您想在单个查询中完成这两项操作,您可以按如下方式进行:
SELECT id, created_at, title, date_trunc('week', created_at) created_week
, COUNT(*) OVER ( PARTITION BY date_trunc('week', created_at) ) weekly_cnt
FROM Questions
在上面的查询中,我将 COUNT(*)
用作 window 函数并按创建问题的周进行分区。