【问题标题】:Postgres query for recursive operation on rows对行进行递归操作的 Postgres 查询
【发布时间】:2017-04-14 02:13:32
【问题描述】:
create table foo (a int, b float);

insert into foo values (1, 2), (2,3),(3,2.5),(4,1.5);

 a |  b  
---+-----
 1 |   2
 2 |   3
 3 | 2.5
 4 | 1.5

我想计算任何a 的每个b 的差异

select RECURSIVE diff (?,?) on b where a=1

输出:

 a |  diff  
---+-----
 1 |   0
 2 |   1
 3 | .5
 4 | -.5

是否可以递归地对所有表行应用函数?

【问题讨论】:

  • 当您在 SQL 查询中使用 where a = 1 时,如何在预期输出中为 a 提供多个值?
  • 可能是子查询?
  • 你能不能解释的更清楚一些,你需要什么?

标签: sql postgresql


【解决方案1】:
select b - b0
from
    foo
    cross join
    (select b as b0 from foo where a = 1) s
;
 ?column? 
----------
        0
        1
      0.5
     -0.5

由于 cmets 中有数千个请求,这是一个优雅的版本:

select f1.b - f2.b
from
    foo f1
    cross join
    foo f2
where f2.a = 1

【讨论】:

  • 就纯粹的风格而言,我认为这看起来要好得多,加上理智的空白和没有虚拟表:SELECT f1.b - f2.b FROM foo AS f2 CROSS JOIN foo AS f2 WHERE f2.a = 1
【解决方案2】:

您可以使用LAG 窗口函数来获取行之间的差异:

SELECT b - LAG(b) OVER (ORDER BY a ASC) 
FROM foo;
┌──────────┐
│ ?column? │
├──────────┤
│   (null) │
│        1 │
│     -0.5 │
│       -1 │
└──────────┘
(4 rows)

然后你可以SUM那个:

SELECT SUM(d) OVER (ORDER BY a ASC)
FROM (
    SELECT a, b - LAG(b) OVER (ORDER BY a ASC)
    FROM foo
) sub(a, d);
┌────────┐
│  sum   │
├────────┤
│ (null) │
│      1 │
│    0.5 │
│   -0.5 │
└────────┘
(4 rows)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-19
    • 1970-01-01
    • 2017-04-18
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    相关资源
    最近更新 更多