返回具有同一组中上一行值的行(Oracle Sql)

时间:2017-10-06 09:57:39

标签: sql oracle12c

我有一个看起来像这样的表格:

|--------+------+---------|------|
| Head   | ID   | Amount  | Rank | 
|--------+------+---------|------|
|      1 | 10   |  1000   |   1  |
|      1 | 11   |  1200   |   2  |
|      1 | 12   |  1500   |   3  |
|      2 | 20   |  3400   |   1  |
|      2 | 21   |  3600   |   2  |
|      2 | 22   |  4200   |   3  |
|      2 | 23   |  1700   |   4  |
|--------+------+---------|------|

我想要一个新列(New_column)执行以下操作:

|--------+------+---------|------|------------| 
| Head   | ID   | Amount  | Rank | New_column | 
|--------+------+---------|------|------------|
|      1 | 10   |  1000   |   1  |  1000      |   
|      1 | 11   |  1200   |   2  |  1000      |
|      1 | 12   |  1500   |   3  |  1200      |
|      2 | 20   |  3400   |   1  |  3400      |
|      2 | 21   |  3600   |   2  |  3400      |
|      2 | 22   |  4200   |   3  |  3600      |
|      2 | 23   |  1700   |   4  |  4200      |
|--------+------+---------|------|------------|

在每个头号中,如果等级不是1,则取头号内的行数与其前的等级数(等级2取同一头内等级1的数量,等级3取等级2的数量)在同一个头等等......)

我知道如何使用其他编程语言中的For循环修复它,但不知道如何使用SQL进行修复。

3 个答案:

答案 0 :(得分:1)

我认为你基本上想要lag()

select t.*,
       lag(amount, 1, amount) over (partition by head order by rank) as new_column
from t;

lag()的三参数形式允许您提供默认值。

答案 1 :(得分:1)

您可以使用此更新:

UPDATE your_table b
SET New_column = CASE WHEN rank = 1 then Amount
                      ELSE (select a.Amount FROM your_table a where a.ID = b.ID and a.rank = b.rank-1) END

答案 2 :(得分:1)

您可以在派生表的rank-1上加入相同的表(子查询)。

   select t1.*,case when t1.rank=1 then amount else t2.amount new_amount 
   from your_table t1 left join (select Head,ID,Amount,Rank from your_table) t2 
   on t1.head=t2.head and t1.rank=t2.rank-1