【问题标题】:How to fill NULL value using min-max in SQL Server?如何在 SQL Server 中使用 min-max 填充 NULL 值?
【发布时间】:2021-03-15 15:56:40
【问题描述】:

我想使用 min-max 比较来获得前值和后值。

这是我的示例表。

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=322aafeb7970e25f9a85d0cd2f6c00d6

例如,这是temp01 表。

我想在 temp01 中获取 start&end NULL 值。

所以,我填写

price = [NULL, NULL, 13000]

price = [12000, 12000, 13000]

因为12000[230, 1] 中的最小值。而我在[cat01, cat02]组中填充了NULL的最大值

    | SEQ | cat01 | cat02 |   dt_day   | price |
    +-----+-------+-------+------------+-------+
    |  1  |  230  |   1   | 2019-01-01 |  NULL |
    |  2  |  230  |   1   | 2019-01-02 |  NULL |
    |  3  |  230  |   1   | 2019-01-03 | 13000 |
                       ...

    |  11 |  230  |   1   | 2019-01-11 |  NULL |
    |  12 |  230  |   1   | 2019-01-12 |  NULL |
    |  1  |  230  |   2   | 2019-01-01 |  NULL |
    |  2  |  230  |   2   | 2019-01-02 |  NULL |
    |  3  |  230  |   2   | 2019-01-03 | 12000 |

                       ...
    |  12 |  230  |   2   | 2019-01-11 |  NULL |
    |  13 |  230  |   2   | 2019-01-12 |  NULL |

[结果]

    | SEQ | cat01 | cat02 |   dt_day   | price | 
    +-----+-------+-------+------------+-------+
    |  1  |  230  |   1   | 2019-01-01 | 12000 | --START
    |  2  |  230  |   1   | 2019-01-02 | 12000 | 
    |  3  |  230  |   1   | 2019-01-03 | 13000 |
    |  4  |  230  |   1   | 2019-01-04 | 12000 |
    |  5  |  230  |   1   | 2019-01-05 |  NULL |  
    |  6  |  230  |   1   | 2019-01-06 |  NULL |
    |  7  |  230  |   1   | 2019-01-07 | 19000 |
    |  8  |  230  |   1   | 2019-01-08 | 20000 |
    |  9  |  230  |   1   | 2019-01-09 | 21500 | 
    | 10  |  230  |   1   | 2019-01-10 | 21500 | 
    | 11  |  230  |   1   | 2019-01-11 | 21500 | 
    | 12  |  230  |   1   | 2019-01-12 | 21500 | 
    | 13  |  230  |   1   | 2019-01-13 | 21500 | --END   
    |  1  |  230  |   2   | 2019-01-01 | 12000 | --START
    |  2  |  230  |   2   | 2019-01-02 | 12000 | 
    |  3  |  230  |   2   | 2019-01-03 | 12000 | 
    |  4  |  230  |   2   | 2019-01-04 | 17000 |
    |  5  |  230  |   2   | 2019-01-05 | 22000 |   
    |  6  |  230  |   2   | 2019-01-06 |  NULL |
    |  7  |  230  |   2   | 2019-01-07 | 23000 |
    |  8  |  230  |   2   | 2019-01-08 | 23200 |
    |  9  |  230  |   2   | 2019-01-09 |  NULL |
    | 10  |  230  |   2   | 2019-01-10 | 24000 |
    | 11  |  230  |   2   | 2019-01-11 | 24000 | 
    | 12  |  230  |   2   | 2019-01-12 | 24000 | 
    | 13  |  230  |   2   | 2019-01-13 | 24000 | --END

请告诉我使用线性关系填充 NULL 的好方法。

【问题讨论】:

  • 因此,如果该行位于第一个非值之前(使用序列),并且您想在最后一个非值之后更新 NULL 值,则您希望更新具有该组最小值的 NULL 价格- 最大值?所有其他你不碰的空值?
  • @AllanWind 是的,对!如果我触摸其他空值,我想使用插值填充。

标签: sql sql-server


【解决方案1】:

找到min()max() 的价格GROUP BY cat01, cat02。 还可以找到 minmax seq 所在行的 price is not null

之后,只需将inner join 添加到您的表并更新where price is null

with val as
(
    select cat01, cat02, 
           min_price = min(price), 
           max_price = max(price),
           min_seq   = min(case when price is not null then seq end),
           max_seq   = max(case when price is not null then seq end)
    from   temp01
    group by cat01, cat02
)
update t
set    price = case when t.seq < v.min_seq then min_price
                    when t.seq > v.max_seq then max_price
                    end
FROM   temp01 t
       inner join val v on   t.cat01 = v.cat01
                        and  t.cat02 = v.cat02
where  t.price is null  

dbfiddle

编辑:将price 作为SELECT 查询中的新列返回

with val as
(
    select cat01, cat02, min_price = min(price), max_price = max(price),
           min_seq = min(case when price is not null then seq end),
           max_seq = max(case when price is not null then seq end)
    from   temp01
    group by cat01, cat02
)
select t.*,
       new_price = coalesce(t.price,
                            case when t.seq < v.min_seq then min_price
                                 when t.seq > v.max_seq then max_price
                                 end)
FROM   temp01 t
       left join val v on t.cat01 = v.cat01
                        and  t.cat02 = v.cat02

Updated dbfiddle

【讨论】:

  • 非常感谢,难道不使用更新条款吗?
猜你喜欢
  • 1970-01-01
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 2017-06-10
相关资源
最近更新 更多