问题
我正在使用数据库中的内核工作,而我的PostgreSQL技能已经碰壁了。我在两个表之间加入来计算交叉乘积,即
SELECT (d1.a * d2.a + d1.b * d2.b) AS dot FROM data d1, data d2
这给了我所有载体之间的交叉产物。在我的表格中包含以下数据
a | b | c
---+---+---
1 | 1 | 1
2 | 2 | 2
3 | 3 | 3
以上命令产生
dot
-----
2
4
6
...
如果我想计算第2行与前一行及其后一行之间的点积,我该如何有效地做到这一点?
尝试
我曾尝试使用窗口函数,但由于它们只计算聚合函数,因此未能这样做。我想连接其相邻行(即其窗口)的行,但不计算任何聚合。这些方面的东西:
SELECT a * a + b * b + c * c
OVER(rows between 1 preceding and 1 following) as value FROM data data;
我也尝试使用row_number() OVER()
。但是对于嵌套的子查询,这看起来很笨拙和低效。
SELECT d1.a * d3.a + d1.b * d3.b + d1.c * d3.c
FROM data d1,
(SELECT * FROM
(SELECT *, row_number() OVER() as index from data) d2
WHERE d2.index >= 1 AND d2.index <=3) d3;
最后,我试图在没有运气的情况下深入了解LATERAL
。
有什么想法吗?
答案 0 :(得分:0)
您可以按lag()
/ lead()
获取前/后行的值
如果行的顺序由a
确定,则查询将如下:
SELECT
a,
(lag(a, 1, 0) OVER (ORDER BY a)) * (lead(a, 1, 0) OVER (ORDER BY a))
+ (lag(b, 1, 0) OVER (ORDER BY a)) * (lead(b, 1, 0) OVER (ORDER BY a))
+ (lag(c, 1, 0) OVER (ORDER BY a)) * (lead(c, 1, 0) OVER (ORDER BY a)) AS dot_preceding_and_following
FROM ( VALUES
(1, 1, 1),
(2, 2, 2),
(3, 3, 3)
) T(a, b, c)
ORDER BY
a
;