【问题标题】:PostgreSQL: Joining with Window Function / Partial TablePostgreSQL:与窗口函数/部分表连接
【发布时间】:2016-09-02 12:34:45
【问题描述】:

问题

我正在做一个使用数据库内核的项目,但我的 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;

最后,我尝试深入了解LATERALs,但没有成功。

有什么想法吗?

【问题讨论】:

  • 需要定义previous和next。 SQL 没有这种结构的概念。此外,示例结果将有助于解释您想要完成的任务。
  • ... compute the dot product between, say, row 2 with its preceding row and its following row, 请定义precedingfollowing。 (定义order,你的问题就解决了)顺便说一句:你的表有主键吗?
  • 假设我们有任意顺序,在示例中,例如列a。我将如何在 a、其自身和 n 个相邻行之间进行连接?

标签: postgresql join window-functions cross-product


【解决方案1】:

您可以通过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
;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 2018-12-15
    • 1970-01-01
    • 2021-04-14
    • 2018-12-08
    • 1970-01-01
    • 2014-05-27
    相关资源
    最近更新 更多