这让我发疯,因为我觉得应该可以。但是我公认我不是一个巨大的SQL天才。
我有一个sqlite3表,看起来基本上是这样的:
id date amount
-- ---- ------
51 2018.10.01 10.0
52 2018.11.15 100.0
53 2018.11.15 20.0
54 2018.09.10 -30.0
(至少,这些是相关的字段;其他字段已被忽略)。
我想做的是生成amount
列的运行总计,但数据按date
排序。
我知道用于计算运行总计的“将表与自身连接起来”的技巧。因此,如果我想为每个id
(一个唯一的字段)提供一个新的运行总价值,我可以这样做:
select T2.id, T2.date, T2.amount, sum(T2.amount)
from Transactions T1
inner join Transactions T2
on T1.id >= T2.id
group by T1.id
我明白了:
"51" "2018.10.01" "10.0" "10.0"
"52" "2018.11.15" "100.0" "110.0"
"53" "2018.11.15" "20.0" "130.0"
"54" "2018.09.10" "-30.0" "100.0"
运行总正确。
但是,如果我希望以date
的顺序运行此数据的总计,则会发生故障。这很接近:
select T1.id, T2.date, T2.amount, sum(T2.amount)
from Transactions T1
inner join Transactions T2
on T1.date >= T2.date
group by T1.date
除了在amount
为date
的两行中对2018.11.15
值进行计数(并合并)之外。大概是因为on T1.date >= T2.date
子句适用于两行,每行两次。
"54" "2018.09.10" "-30.0" "-30.0"
"51" "2018.09.10" "-30.0" "-20.0"
"53" "2018.09.10" "-30.0" "200.0"
如我所见,只有在对值都是唯一且已排序的字段执行join
时,此技术才有效。一旦我按date
对表格进行排序,唯一的id
值就会乱序并且不再可用。
因此,我想到了-也许首先按date
对表进行排序,然后添加一个临时表,其中包含唯一的排序数字。只需行号即可。
不幸的是,这似乎是不支持row_number()
,rownum
或over
子句中任何一种的sqlite版本。
我知道这种生成行号的技术:
select id, date,
(select count(*) from Transactions T1 where T1.id <= T2.id)
from Transactions T2
"51" "2018.10.01" "1"
"52" "2018.11.15" "2"
"53" "2018.11.15" "3"
"54" "2018.09.10" "4"
但是我几乎没有摆弄任何办法:
date
count(*)
技术生成唯一的行号join
与其自身的表一起创建运行总计在单个SQL语句中。
希望这是有道理的。感谢任何人的任何想法。
答案 0 :(得分:0)
如果您使用的是Sqlite 3.25或更高版本,则使用窗口函数可以简化此操作。示例:
首先,用示例数据填充表格:
CREATE TABLE example(id INTEGER PRIMARY KEY, date TEXT, amount REAL);
INSERT INTO example VALUES(51,'2018-10-01',10.0);
INSERT INTO example VALUES(52,'2018-11-15',100.0);
INSERT INTO example VALUES(53,'2018-11-15',20.0);
INSERT INTO example VALUES(54,'2018-09-10',-30.0);
(请注意,我将日期格式更改为sqlite日期和时间功能可以理解的格式,因为这样一来,您想进行比排序更复杂的操作就可以使工作变得更加轻松。)
查询
SELECT *, sum(amount) OVER (ORDER BY date, id) AS running_total
FROM example
ORDER BY date, id;
产生:
id date amount running_total
---------- ---------- ---------- -------------
54 2018-09-10 -30.0 -30.0
51 2018-10-01 10.0 -20.0
52 2018-11-15 100.0 80.0
53 2018-11-15 20.0 100.0
如果您使用的是较旧的版本,则您真正应该考虑升级的原因不仅仅是拥有窗口功能。
答案 1 :(得分:0)
谢谢肖恩(Shawn)–您使我步入正轨。
它看起来像是针对SQLite的DB浏览器的最新beta版本确实支持窗口功能(我想是因为最新版本的SQLite本身支持)。
问题解决了!