使用'parititon by'和窗口函数在postgres中返回多于一行?

Posted

技术标签:

【中文标题】使用\'parititon by\'和窗口函数在postgres中返回多于一行?【英文标题】:using 'parititon by' and window functions to return more then one row in postgres?使用'parititon by'和窗口函数在postgres中返回多于一行? 【发布时间】:2019-08-21 12:05:33 【问题描述】:

:)

我正在学习 Postgresql,使用 11.4 版

我的表中有一些行通过它们的公共 ID(我们称之为列 common_id)和方向(12)与其他行相关。

每个common_id可以而且必须只有一个方向1,从方向2可以有0到10行。

桌子很大,所以我不想加入同一张桌子,我有两种情况,我解决了一个..没有解决另一个。

假设我有下表:

common_id | direction | price | time 
1           1           0       1
2           1           1       4
2           2           2.5     5
3           1           5       8
3           2           7       10
3           2           10      12

所以第一种情况是将方向为1 的行连接到direction 2 的最新时间行。当然都在同一个common_id

所以在这里我可以只做PARTITION BY common_id order by direction, time RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWINGfirst_value() 是方向1 的线和last_value() 是方向2 的线如果count(1) 大于1,如果不是那么没有方向2

结果如下:

common_id  | price_1 | time_1 | price_2 | time_2
1            0         1        null      null
2            1         4        2.5       5
3            5         8        10        12

这项工作进展迅速,我很高兴。所以这里对于每个common_id 我都有一行。但是当我需要为每个分区设置多于一行时会发生什么?

第二种情况是我需要为每个common_id 获取方向为2 的所有行,并将具有相同common_id 的行与方向1 连接到每一行。

所以这里的预期结果应该是:

common_id  | price_1 | time_1 | price_2 | time_2
2            1         4        2.5       5
3            5         8        7         10
3            5         8        10        12

如果有一种方法可以使用 PARTITION BY 解决它,我会很高兴,如果不是其他解决方案,但由于性能问题,我不能使用另一个连接到同一个表,因为它是一个非常大的表。

我希望我正确地解释了自己。

谢谢你

【问题讨论】:

【参考方案1】:

试试这个(未经测试的)查询:

SELECT common_id,
       price_1,
       time_1,
       price_2,
       time_2
FROM (SELECT common_id,
             direction,
             first_value(price) OVER w AS price_1,
             first_value(time) OVER w AS time_1,
             price AS price_2,
             time AS time_2
      FROM atable
      WINDOW w AS (PARTITION BY common_id
                   ORDER BY direction
                   ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
     ) q
WHERE direction = 2;

【讨论】:

以上是关于使用'parititon by'和窗口函数在postgres中返回多于一行?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在窗口函数中使用 GROUP BY

无法在 Oracle 的窗口函数中使用 ORDER BY 子句

使用具有不同 order by 子句的 postgres 窗口函数

SQL (Hive):在使用 GROUP BY 进行聚合时使用窗口函数

SQL Group By和窗口函数

使用窗口函数时,hive 是不是支持 PARTITION BY 语句中的复杂类型?