【问题标题】:SQL Show the previous value until the given value changesSQL 显示前一个值,直到给定值改变
【发布时间】:2021-04-20 13:02:22
【问题描述】:

我有一个按 ID 排序的表格,其中列有 Value

| ID       | Value          |
| -------- | -------------- |
| 1        | 50             |
| 2        | 50             |
| 3        | 62             |
| 4        | 62             |
| 5        | 62             |
| 6        | 79             |
| 7        | 90             |
| 8        | 90             |

我想创建另一列 Prev_ValueValue 的每一行采用与当前行值不同的前一个/前一个数字,如表中所示下面。

输出表:

| ID       | Value          |Prev_Value     |
| -------- | -------------- |---------------|
| 1        | 50             |NULL           |
| 2        | 50             |NULL           |
| 3        | 62             |50             |
| 4        | 62             |50             |
| 5        | 62             |50             |
| 6        | 79             |62             |
| 7        | 90             |79             |
| 8        | 90             |79             |

我应该使用修改后的 LAG() 函数、CROSS APPLY 还是嵌套 CASE,哪种方法最省时?任何帮助将不胜感激。

不幸的是,这里有一些参考资料不能解决我的问题: LAG(offset) until value is reached in BigQuerySQL Server : select distinct until the value is changed

【问题讨论】:

  • 值是否一直在增加?
  • 不,它们也可能会减少。我应该在问题中提到它。
  • 。 .使用累积最大值会稍微容易一些。

标签: sql sql-server tsql


【解决方案1】:

一种方法使用apply

select t.*, tprev.value
from t outer apply
     (select top (1) tprev.*
      from t tprev
      where tprev.value <> t.value and
            tprev.id < t.id
      order by tprev.id desc
     ) tprev;

以上方法在大型数据集上并不是最有效的方法。为此,我建议第一次获得值更改并标记它。

select t.*,
        max(case when prev_value <> value then prev_value end) over (partition by grp) as prev_value
from (select t.*,
             sum(case when prev_value = value then 0 else 1 end) over (order by id) as grp
      from (select t.*,
                   lag(value) over (order by id) as prev_value
            from t
           ) t
     ) t;

Here 是一个 dbfiddle。

【讨论】:

    【解决方案2】:

    这是一种方法。 (在this fiddle 上实时查看)

     select 
        t1.*, 
        t2.value prev_value  
    from 
        t t1 
        left join t t2 on t2.id = (select max(id) from t where value<t1.value)
    

    【讨论】:

    • 我应该提到,“值”列在以下行中可能具有较低的数字,例如较高的 id。 (ID, 值) (8, 92) (9, 75)
    猜你喜欢
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 2016-11-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多