我需要查询每一分钟到该分钟为止的总行数。
到目前为止,我能取得的最好成绩并不能解决问题。它返回每分钟的计数,而不是每分钟的总计数:
SELECT COUNT(id) AS count
, EXTRACT(hour from "when") AS hour
, EXTRACT(minute from "when") AS minute
FROM mytable
GROUP BY hour, minute
SELECT DISTINCT
date_trunc('minute', "when") AS minute
, count(*) OVER (ORDER BY date_trunc('minute', "when")) AS running_ct
FROM mytable
ORDER BY 1;
使用date_trunc()
,它恰好返回您需要的内容。
不要包含id
在查询中,因为您希望记录GROUP BY
切片。
count()
通常用作简单的聚合函数。附加OVER
子句使其成为窗口函数。PARTITION BY
在窗口定义中忽略-您希望 对所有 行进行 运行计数 。默认情况下,按定义从当前行的第一行到最后一行ORDER BY
。我引用该手册:
默认的取景选项为
RANGE UNBOUNDED PRECEDING
,与相同RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
。使用ORDER BY
,这会将帧设置为从分区开始到当前行的最后一个ORDER BY
对等方的所有行。
而这恰好 正是 您所需要的。
使用count(*)
而不是count(id)
。它更适合您的问题(“行数”)。它通常是稍 快 比count(id)
。而且,尽管我们可以假设id
为NOT NULL
,但尚未在问题中指定它,因此严格来说count(id)
是 错误的 ,因为NULL值不计入count(id)
。
您不能GROUP BY
在相同的查询级别上记录切片。集合函数 在 窗口函数 之前 应用,这样窗口函数count(*)
每分钟只能看到1行。
但是,您可以使用,SELECT DISTINCT
因为它DISTINCT
是 在 窗口功能 之后 应用的。
ORDER BY 1
只是ORDER BY date_trunc('minute', "when")
这里的简写。
1
是对SELECT
列表中第一个表达式的位置参考。
使用to_char()
,如果你需要格式化的结果。喜欢:
SELECT DISTINCT
to_char(date_trunc(‘minute’, “when”), ‘DD.MM.YYYY HH24:MI’) AS minute
, count(*) OVER (ORDER BY date_trunc(‘minute’, “when”)) AS running_ct
FROM mytable
ORDER BY date_trunc(‘minute’, “when”);
SELECT minute, sum(minute_ct) OVER (ORDER BY minute) AS running_ct
FROM (
SELECT date_trunc('minute', "when") AS minute
, count(*) AS minute_ct
FROM tbl
GROUP BY 1
) sub
ORDER BY 1;
类似于上面的内容,但是:
我使用子查询来汇总和计算每分钟的行数。这样,我们每分钟就能获得1行,而不会DISTINCT
在外部SELECT
。
用sum()
现在的窗口集合函数从子查询加起来计数。
我发现这样做的速度大大提高,每分钟有很多行。
@GabiMe在评论中询问如何在时间范围内的 每个
minute
时间获取eone行,包括没有事件发生的行(基表中没有行):
SELECT DISTINCT
minute, count(c.minute) OVER (ORDER BY minute) AS running_ct
FROM (
SELECT generate_series(date_trunc('minute', min("when"))
, max("when")
, interval '1 min')
FROM tbl
) m(minute)
LEFT JOIN (SELECT date_trunc('minute', "when") FROM tbl) c(minute) USING (minute)
ORDER BY 1;
在第一个事件与最后一个事件之间的时间范围内,每分钟产生一行generate_series()
-使用-这里直接基于子查询的汇总值。
LEFT JOIN
所有时间戳都将被截断至分钟并计数。NULL
值(不存在行)不会添加到运行计数中。
使用CTE:
WITH cte AS (
SELECT date_trunc('minute', "when") AS minute, count(*) AS minute_ct
FROM tbl
GROUP BY 1
)
SELECT m.minute
, COALESCE(sum(cte.minute_ct) OVER (ORDER BY m.minute), 0) AS running_ct
FROM (
SELECT generate_series(min(minute), max(minute), interval '1 min')
FROM cte
) m(minute)
LEFT JOIN cte USING (minute)
ORDER BY 1;
再次,在第一步中汇总并计算每分钟的行数,而忽略了稍后的需求DISTINCT
。
不同于count()
,sum()
可以退货NULL
。默认为0
with COALESCE
。
在使用Postgres 9.1-9.4测试的几个变体中 ,"when"
该版本具有很多行和一个带有子查询的 索引 是最快的:
SELECT m.minute
, COALESCE(sum(c.minute_ct) OVER (ORDER BY m.minute), 0) AS running_ct
FROM (
SELECT generate_series(date_trunc('minute', min("when"))
, max("when")
, interval '1 min')
FROM tbl
) m(minute)
LEFT JOIN (
SELECT date_trunc('minute', "when") AS minute
, count(*) AS minute_ct
FROM tbl
GROUP BY 1
) c USING (minute)
ORDER BY 1;
我在表中插入了一个数据......我现在想看到整个表的行,列和数据。如何通过命令显示?
问题内容: 我有要求在5分钟内运行一会儿循环。我寻找了计时器api,但找不到这样做。任何人都可以为此提供代码摘要。 谢谢 问题答案: 最简单的方法是只检查每次迭代已花费了多少时间。例: 这将运行循环,直到超过5分钟为止。 笔记: 当前循环迭代将始终完成,因此在实践中它将始终运行5分钟以上。 对于此应用程序而言,它比之更合适,因为如果调整了计算机的系统时钟,后者将发生变化,从而使计算工作中断。 感谢
问题内容: 我在Postgres服务器上有以下数据库表: 我想创建一个查询,给出了的按月份和年份如下列并对结果进行分组: 有没有简单的方法可以做到这一点? 问题答案: 应Radu的要求,我将解释该查询: :将“日期”属性转换为月的简短形式的定义格式。 :Postgresql的“提取”功能用于从“日期”属性中提取YYYY年。 :SUM()函数将所有“ Sales”值相加,并提供区分大小写的别名,并使
问题内容: 我有一个监视系统,它每n秒收集一次数据(n大约为10,但有所不同)。我想每隔15分钟汇总一次收集的数据。有没有一种方法可以将时间戳记值合并为15分钟的块,以便分组工作? 问题答案:
比方说,我有一个购物车的食品杂货,每个项目都有一个唯一的ID。当有人点击“购买”时,会发送一个数组,其中包含购物车中每件商品的对象。购物车各不相同,所以有时可能是2个项目,有时是6个项目,等等。 例子: 我需要我的SQL表“可用的杂货”来根据购买的商品进行更新。 对于一个杂货项目,我会使用以下内容: 既然我现在有多件商品,我如何让查询为购买的每件商品运行?或者作为一个大规模的查询,根据购买的商品数
问题内容: 因此,我想尝试一下Timer和TimerTask类。 30秒过后,我能够执行一行代码。我现在一直想做的是让这行代码执行5分钟。 这是我最初尝试的 我在for循环中使用了数字10,以查看timer.schedule在循环的下一次迭代期间是否还要再等待30秒。 知道我应该怎么做吗?我尝试将schedule方法与传入参数period一起使用,但这只是使其重新执行而从未停止过。 问题答案: 您