SELECT Country, Gdp, SUM(Gdp) OVER (ROWS UNBOUNDED PRECEDING)
FROM CountryGdp;
这是一个完成请求的最小查询,但它没有定义任何排序,因此这里有一个更合适的方法。
SELECT
Country,
Gdp,
SUM(Gdp) OVER (
ORDER BY Country -- Window ordering (not necessarily the same as result ordering!)
ROWS BETWEEN -- Window for the SUM includes these rows:
UNBOUNDED PRECEDING -- all rows before current one in window ordering
AND CURRENT ROW -- up to and including current row.
) AS RunningTotal
FROM CountryGdp
ORDER BY Country;
WITH RECURSIVE running(id, name, gdppc, rt) AS (
SELECT row1._rowid_, row1.name, row1.gdppc, COALESCE(row1.gdppc,0)
FROM gdppc AS row1
WHERE row1._rowid_ = (
SELECT a._rowid_
FROM gdppc AS a
ORDER BY a.gdppc, a.name, a._rowid_
LIMIT 1)
UNION ALL
SELECT row_n._rowid_, row_n.name, row_n.gdppc, COALESCE(row_n.gdppc,0)+running.rt
FROM gdppc AS row_n INNER JOIN running
ON row_n._rowid_ = (
SELECT a._rowid_
FROM gdppc AS a
WHERE (a.gdppc, a.name, a._rowid_) > (running.gdppc, running.name, running.id)
ORDER BY a.gdppc, a.name, a._rowid_
LIMIT 1))
SELECT running.name, running.gdppc, running.rt
FROM running;
如果你有一个不支持OVER的SQLite版本,这里有另一种方法,对行的group_concat字符串使用递归。 在SQLite version 3.22.0 2018-01-22 18:45:57 group_concat上,按数据库顺序返回行。创建一个公共表表达式,并按不同顺序对其排序,如示例中的表work 1。
/* cumulative running total using group_concat and recursion
adapted from https://blog.expensify.com/2015/09/25/the-simplest-sqlite-common-table-expression-tutorial/
*/
WITH RECURSIVE work2 AS (
SELECT NULL AS name, NULL AS gdppc, 0 AS cum, (select group_concat(name) from work1) AS gcname, (select group_concat(gdppc) from work1) AS gcgdppc
UNION
SELECT
CASE
WHEN INSTR(gcname, ',' )>0 THEN
SUBSTR(gcname, 0, INSTR(gcname,','))
ELSE
gcname
END,
CASE
WHEN INSTR(gcgdppc, ',' )>0 THEN
SUBSTR(gcgdppc, 0, INSTR(gcgdppc,','))
ELSE
gcgdppc
END,
CASE
WHEN INSTR(gcgdppc, ',' )>0 THEN
cum + SUBSTR(gcgdppc, 0, INSTR(gcgdppc,','))
ELSE
cum + gcgdppc
END,
CASE
WHEN INSTR( gcname, ',' )>0 THEN
SUBSTR( gcname, INSTR( gcname, ',' )+1 )
ELSE
NULL
END,
CASE
WHEN INSTR(gcgdppc, ',' )>0 THEN
SUBSTR( gcgdppc, INSTR( gcgdppc, ',' )+1 )
ELSE
NULL
END
FROM work2
WHERE gcgdppc IS NOT NULL
),
/* SQLite version 3.22.0 2018-01-22 18:45:57
group_concat ignores ORDER BY when specified against the base table
but does appear to follow the order of a common table expression
*/
work1 AS (select * from gdppc order by gdppc),
gdppc AS (SELECT 'Burundi' AS name,399.657 AS gdppc
UNION
SELECT 'Democratic Republic of Congo', 329.645
UNION
SELECT 'Liberia',385.417
UNION
SELECT 'Zimbabwe',370.465)
select name,gdppc,cum from work2 where name IS NOT NULL;
/* result
Democratic Republic of Congo|329.645|329.645
Zimbabwe|370.465|700.11
Liberia|385.417|1085.527
Burundi|399.657|1485.184
*/
由于这篇文章是谷歌搜索“sqlite滚动求和”的最佳结果,我将添加下面的答案。 top answer by relatively_random非常适合累计求和。但是,如果您想将其调整为滚动求和(可能是7天滚动求和),可以通过添加CASE表达式来检查窗口是否具有所需的大小(例如7)。1 这是必要的(?),因为通常情况下,如果滚动窗口的大小小于预期大小,滚动计算将返回NULL。例如,如果我们正在计算7天的滚动总和,则前6行的总计应为NULL,因为还不到7天。
SELECT
date,
price,
CASE
WHEN COUNT(*) OVER win >= 7 THEN SUM(price) OVER win
END AS seven_day_rolling_total
FROM price_data
WINDOW win AS (
ORDER BY date
ROWS 6 PRECEDING
)
--LIMIT 10;
6条答案
按热度按时间0ve6wy6x1#
自2018年9月15日起,SQLite 3.25.0支持window functions及其关键字
OVER
。现在,您的问题的答案很简单:这是一个完成请求的最小查询,但它没有定义任何排序,因此这里有一个更合适的方法。
时间复杂度为O(N)。
9rnv2umw2#
您可以通过将表与其自身联接(执行所谓的笛卡尔联接或交叉联接)来实现此目的。请参阅以下示例。
给定一个包含国家及其人均GDP的表格,它会给你一个GDP数字的运行总数。
注意,这可能是一个非常耗费资源的操作,因为如果一个表有N个元素,它将创建一个有N*N个元素的临时表。
mum43rcc3#
.(N^2)时间复杂度:O(N^2)时间复杂度:O(N^2)时间复杂度:.(N^2)时间复杂度:.(N^2)
这会产生与他相同的输出。
排序和比较处理重复项,
COALESCE
用于忽略NULL。如果你有一个很好的索引,那么这应该是O(N log N)。因为SQLite不支持游标,所以如果不依赖于外部应用程序,O(N)的解决方案可能不存在。
o8x7eapl4#
如果你有一个不支持OVER的SQLite版本,这里有另一种方法,对行的group_concat字符串使用递归。
在SQLite version 3.22.0 2018-01-22 18:45:57 group_concat上,按数据库顺序返回行。创建一个公共表表达式,并按不同顺序对其排序,如示例中的表work 1。
ghhkc1vu5#
由于这篇文章是谷歌搜索“sqlite滚动求和”的最佳结果,我将添加下面的答案。
top answer by relatively_random非常适合累计求和。但是,如果您想将其调整为滚动求和(可能是7天滚动求和),可以通过添加CASE表达式来检查窗口是否具有所需的大小(例如7)。1
这是必要的(?),因为通常情况下,如果滚动窗口的大小小于预期大小,滚动计算将返回NULL。例如,如果我们正在计算7天的滚动总和,则前6行的总计应为NULL,因为还不到7天。
1:为了使查询更容易阅读,我在SELECT语句之后定义了窗口,因为它被使用了两次。
hgqdbh6s6#
您必须在所需字段中进行求和....查询取决于您使用的数据库,Oracle允许您执行以下操作: