简体   繁体   中英

Return the row with the value of the previous row within the same group (Oracle Sql)

I have a tabel that looks like this:

|--------+------+---------|------|
| 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  |
|--------+------+---------|------|

I want a new column ( New_column ) that does the following:

|--------+------+---------|------|------------| 
| 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      |
|--------+------+---------|------|------------|

Within each Head number, if rank is not 1, takes the amount of row within the Head number with Rank number before it (Rank 2 takes the amount of Rank 1 within the same Head and Rank 3 takes the amount of Rank 2 within the same Head and so on...)

I know how to fix it with a For loop in other programming languages but Don't know how to do it with SQL .

I think you basically want lag() :

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

The three-argument form of lag() allows you to provide a default value.

You can use this update:

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

You can join the same table(subquery) on rank-1 of derived table.

   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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM