我有以下数据库表:
date a b c d add result
23.02.07 A B C1 D1 1 1
24.02.07 A B C1 D1 0 1
25.02.07 A B C1 D1 1 2
26.02.07 A B C1 D1 1 3
27.02.07 A B C1 D1 1 4
28.02.07 A B C1 D1 0 4
01.03.07 A B C1 D1 0 4
02.03.07 A B C1 D1 0 4
03.03.07 A B C1 D1 1 5
04.03.07 A B C1 D1 0 5
05.03.07 A B C1 D1 0 5
06.03.07 A B C1 D1 0 5
07.03.07 A B C1 D1 2 7
17.02.07 A B C2 D2 1 1
18.02.07 A B C2 D2 0 1
19.02.07 A B C2 D2 0 1
20.02.07 A B C2 D2 0 1
21.02.07 A B C2 D2 0 1
22.02.07 A B C2 D2 0 1
23.02.07 A B C2 D2 0 1
24.02.07 A B C2 D2 0 1
25.02.07 A B C2 D2 1 2
26.02.07 A B C2 D2 3 5
27.02.07 A B C2 D2 1 6
28.02.07 A B C2 D2 0 6
列结果(最后一个)不是实际数据集的一部分。本专栏展示了我想要实现的目标。 基本上我是summin'以前的所有值"添加"通过使用如下的分析函数来确定给定分区的当前分区:
SUM(add) OVER(PARTITION BY
A,
B,
C,
D,
ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS result
这种方法有效,但在查询大量数据时速度很慢。
更多见解:
有更好/更高效的方法吗?
答案 0 :(得分:0)
您的ORDER BY
不具有确定性(多个行的每个分区具有相同的date
)。使用框架定义 ROWS
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
,您的查询结果可以在不同的调用之间进行更改。
Read the definitions in the manual carefully.
默认框架定义为 RANGE
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
,这可能对您的情况更有意义:它会按排序顺序添加当前行的所有对等项(当天)在分区中),因此在同一天分区中的所有行都得到相同的总数。
使排序顺序具有确定性(例如,通过将PK添加为最后ORDER BY
项)或切换到RANGE
。由于RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
是默认值,因此您可以简化:
SUM(add) OVER(PARTITION BY A, B, C, D ORDER BY date)
date
处理这是不对的:
日期有一个btree索引(不是日期数据类型,但字符不同)。
这是一个带来后果的错误。永远不要将日期存储为varchar
,将日期存储为date
。即使ORDER BY date
应发生以正确使用您的特定字符串格式(&#39; 23.02.07&#39; ,就像您在问题中所做的那样< strong> 不 ),它仍然较慢。而且容易出错。存储空间更大(同样也更慢)。
除此之外,具有匹配顺序的索引列的多列索引可以提高性能(like Thorsten commented):
CREATE INDEX foo ON tbl (A, B, C, D, date, add);
您可以使用此索引对物理表进行聚类,以获得更快的结果:
详细信息取决于完整情况:Postgres版本,表格定义,完整查询,......