在不使用子查询的情况下选择行中的上一个值

use*_*199 2 postgresql select postgresql-11

假设您在 PostgreSQL 11 中有一个表,其中包含如下所示的值集。

12 18
11 12
5  12
9  18
7  19
14 18
11 16
6  12
4  11
5  9
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以在不使用子选择的情况下进行选择,或者通过使用函数或触发器/函数来查找每个值低于先前值或可能高于先前值的位置,但此示例低于先前值(可能是 2 行或15+ 行)在列和第一列中都高于最后一行或第一列和第二列以终止选择,使条件为正?

我不知道如何在选择中包含当前变量。如果我可以回顾变量那么我应该能够做到这一点。我想知道是否有人遇到过这个问题,并使其在选择中工作,或者他们在数据库之外进入 GoLang / Python / C++ / Perl / PHP / 等。一旦我离开数据库,做起来非常简单,但我我真的很想将其保留在 PostgreSQL 11 中。

McN*_*ets 6

正如Akina在评论中指出的那样,LAG( ) 函数需要 ORDER BY 子句来显示正确的值。

给出下一个例子:

CREATE TABLE t (id int, bar int);

INSERT INTO t VALUES
(1, 7),
(2, 8),
(3, 30),
(4, 25),
(5, 24),
(6, 24),
(7, 35),
(8, 40);
Run Code Online (Sandbox Code Playgroud)

可以bar通过 获取前一行的值id,(如果不设置顺序,前一行是多少?)

SELECT
    id,
    bar,
    LAG(bar) OVER (ORDER BY id)
FROM
    t;

id | bar |  lag
-: | --: | ---:
 1 |   7 | null  --<< Note the NULL value
 2 |   8 |    7
 3 |  30 |    8
 4 |  25 |   30
 5 |  24 |   25
 6 |  24 |   24
 7 |  35 |   24
 8 |  40 |   35
Run Code Online (Sandbox Code Playgroud)

然后只需使用条件语句IF 或 CASE

SELECT
    id,
    bar,
    CASE 
        WHEN LAG(bar) OVER (ORDER BY id) < bar THEN 'Lower'
        WHEN LAG(bar) OVER (ORDER BY id) > bar THEN 'Higher'
        WHEN LAG(bar) OVER (ORDER BY id) = bar THEN 'Equal'
        ELSE 'Nothing to compare'
    END As Previous
FROM
    t;

id | bar | previous          
-: | --: | :-----------------
 1 |   7 | Nothing to compare
 2 |   8 | Lower             
 3 |  30 | Lower             
 4 |  25 | Higher            
 5 |  24 | Higher            
 6 |  24 | Equal             
 7 |  35 | Lower             
 8 |  40 | Lower            
Run Code Online (Sandbox Code Playgroud)

db<>在这里摆弄