Sql 自上一个空值之后获取第一个非空值的延迟

Sql 自上一个空值之后获取第一个非空值的延迟,sql,amazon-redshift,lag,window-functions,Sql,Amazon Redshift,Lag,Window Functions,下面是我试图在红移数据库中实现的一个示例 我有一个变量current\u value,我想创建一个新的列value\u desired,即: 如果前一行为空,则与当前值相同 如果前一行为非空值,则等于前一行的最后一个非空值 这听起来很容易,但我还没有找到一个方法来做 row_numb current_value value_desired 1 2 3 47 47 4 5 45 45 6

下面是我试图在红移数据库中实现的一个示例

我有一个变量
current\u value
,我想创建一个新的列
value\u desired
,即:

  • 如果前一行为空,则与当前值相同
  • 如果前一行为非空值,则等于前一行的最后一个非空值
这听起来很容易,但我还没有找到一个方法来做

row_numb     current_value   value_desired
1
2
3            47              47
4
5            45              45
6
7
8            42              42
9            41              42
10           40              42
11           39              42
12           38              42
13
14           36              36
15
16
17           33              33
18           32              33
我尝试过LAG()函数,但只能得到前面的值(不是“non null”块中的第一个值),以下是我的看法:

SELECT *
    , CASE WHEN current_value is not null and LAG(current_value) is null THEN current_value
           WHEN current_value is not null and LAG(current_value) is not null 
            THEN LAG(current_value)
      ELSE NULL END AS value_desired
  FROM test1
非常感谢您的帮助。

请使用FIRST\u VALUE()而不是LAG()


请参阅:

以下是正确答案,它给出了正确的结果。 这里有一些聪明的技巧,我建议你仔细看一遍,让我知道需要澄清的地方

根据您的问题创建测试数据

drop table if exists test_table ;
create table test_table (row_num int,current_value int);
insert into test_table(row_num, current_value)
values
  (1,null),
(2,null),
(3,47),
(4,null),
(5,45),
(6,null),
(7,null),
(8 ,42),
(9 ,41),
(10,40  ),
(11,39 ),
(12,38 ),
(13,null),
(14,36),
(15,null),
(16,null),
(17 ,33),
(18,32  )
;
然后运行此代码

SELECT DISTINCT
  j1.row_num,
  CASE WHEN j1.current_value IS NULL
    THEN NULL
  ELSE
    last_value(j2.current_value)
    OVER (
      PARTITION BY j1.row_num
      ORDER BY j2.row_num
      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) END AS value_desired
FROM test_table AS j1
  LEFT JOIN (SELECT
               row_num,
               current_value,
               lag(current_value, 1)
               OVER (
                 ORDER BY row_num ) AS prev_cval
             FROM test_table) AS j2
    ON j1.row_num >= j2.row_num AND j2.current_value IS NOT NULL
       AND j2.prev_cval IS NULL
ORDER BY j1.row_num;
我们的测试数据

DROP TABLE IF EXISTS test_table;
CREATE TABLE test_table (
  row_num       INT,
  current_value INT
);

INSERT INTO test_table (row_num, current_value)
VALUES
  (1, NULL),
  (2, NULL),
  (3, 47),
  (4, NULL),
  (5, 45),
  (6, NULL),
  (7, NULL),
  (8, 42),
  (9, 41),
  (10, 40),
  (11, 39),
  (12, 38),
  (13, NULL),
  (14, 36),
  (15, NULL),
  (16, NULL),
  (17, 33),
  (18, 32);
我们知道:

  • 当当前_值不为null且前一个当前_值为null时,所需的_值等于当前_值
    • 让我们根据下面的q_first_desired_value子查询将其称为first_desired_value
    • 当第一个期望值不为空时,它就是我们期望的值
    • 我们只需要在当前值不为null时,将第一个所需的值传播到其他行
  • 当当前_值不为空时,所需值为所有前一行(当前行旁边)的最后一个第一个_所需值,不包括可能在前一帧中添加的空值
鉴于上述情况,查询如下

WITH q_first_desired_value AS
(
    SELECT
      row_num,
      current_value,
      CASE WHEN LAG(current_value, 1)
                OVER (
                  ORDER BY row_num ) IS NULL
        THEN current_value
      ELSE NULL END AS first_desired_value
    FROM test_table
    ORDER BY row_num
)
SELECT
  row_num,
  current_value,
  CASE WHEN first_desired_value IS NOT NULL
    THEN first_desired_value
  WHEN current_value IS NOT NULL
    THEN LAST_VALUE(first_desired_value) IGNORE NULLS
    OVER (
    ORDER BY row_num ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) END AS desired_value
FROM q_first_desired_value;

请参见函数。请您将问题更新为“从上一个空值开始延迟获取第一个非空值)这不是问题的答案,但可能会有所帮助。