![](/img/trans.png)
[英]Subtract current row from previous row, keeping previous row value as constant — SQL
[英]SQL: Use value from previous row to populate current row
我有兩個表table1和table2像這樣。 你可以看到時間有差距
table1
date item time amount
----------------------------
1/1/2000 a 1 100
1/1/2000 a 2 100
1/1/2000 a 3 200
1/1/2000 a 6 300
1/1/2000 b 1 100
1/1/2000 b 2 100
1/1/2000 b 5 200
2/1/2000 a 1 500
2/1/2000 a 3 500
2/1/2000 a 4 550
我也有table2填補空白
table2
date item time amount new
-------------------------------------------
1/1/2000 a 1 100 N
1/1/2000 a 2 100 N
1/1/2000 a 3 200 N
1/1/2000 a 4 Y <-- added amount should be 200
1/1/2000 a 5 Y <-- added amount should be 200
1/1/2000 a 6 300 N
1/1/2000 b 1 100 N
1/1/2000 b 2 100 N
1/1/2000 b 3 Y <-- added amount should be 100
1/1/2000 b 4 Y <-- added amount should be 100
1/1/2000 b 5 200 N
2/1/2000 a 1 500 N
2/1/2000 a 2 500 N
2/1/2000 a 3 Y <-- added amount should be 500
2/1/2000 a 4 550 N
金額的缺口行應采用上一次/上一次的值。 我能夠識別缺失的行並添加間隙行但我嘗試將金額復制到間隙行但是沒有成功。 我在stackoverflow中查看了我認為類似的問題,並嘗試了解決方案,但它不起作用,如:
update t2
set t2.amount = t1.amount
from table2 t2
inner join table1 t1 on t2.date = t1.date and t1.item = t2.item
where t2.new = 'Y'
and t2.time > (select t2.time
from table1 t3
where max(t3.time) < t2.time)
update t2
set t2.amount = t1.amount
from table1 t1
inner join table2 t2 on t1.date = t2.date and t1.item = t2.item
where t2.new = 'Y' and max(t1.time) < t2.time
有誰知道如何訪問前一行的金額? 游標可以工作,但這是最后的解決方案。 感謝您在忙碌的一天中抽出時間來幫忙。
添加我的創建表代碼
create table #table1 (or #table2)
(
date smalldatetime,
item char(1),
[time] int,
amount int
,new char(1) -- for new row flag
)
您需要找到以前的非空值amount
:
update t
set amount = (
select amount from table2
where
date = t.date and item = t.item and time = (
select max(time) from table2
where
date = t.date and item = t.item
and time < t.time and amount is not null and new = 'N'
)
)
from table2 t
where t.amount is null and t.new = 'Y'
看演示 。
你應該使用窗口查詢:
select
*,sum(amount) over (partition by time order by time) as previous_amount_for_null_values
from table2
也許這個Oracle解決方案會有所幫助(我希望,sql-server有類似rownum或類似的解決方案)。 首先,訂購您的數據並獲得一個唯一的數字(使用rownum偽列)。 其次,對於每個數字計算最大前一個數字非空值。 加入數據。
也許有一個具有分析功能的解決方案,但不,我沒有想到的。
-- create test data
drop table tab1;
create table tab1 (
ym varchar2(7),
val number
);
insert into tab1 values('2016/01',3);
insert into tab1 values('2016/04',6);
insert into tab1 values('2016/08',4);
insert into tab1 values('2016/09',2);
insert into tab1 values('2016/01',5);
insert into tab1 values('2016/09',8);
insert into tab1 values('2016/05',7);
insert into tab1 values('2016/12',3);
insert into tab1(ym) values('2016/03');
insert into tab1(ym) values('2016/11');
insert into tab1(ym) values('2016/12');
insert into tab1(ym) values('2016/12');
-- solution
with q0 as (-- get rownum for each row
select a.*, rownum as rnm -- get rownums
from (
select *
from tab1
order by ym -- order by, to further get proper order numbers from rownum
) a
),
q1 as (-- for each rnm get previous (maximal) rnm with non missing value
select a.rnm, max(b.rnm) as rnm_prev
from q0 a
left join q0 b on a.rnm > b.rnm and b.val is not null -- get only smaller rnms with values
group by a.rnm
)
select q0.ym, q0.rnm, q1.rnm_prev,
q0.val, pv.val as val_prev, nvl(q0.val, pv.val) as val_cor
from q0
left join q1 on q0.rnm = q1.rnm
left join q0 pv on q1.rnm_prev = pv.rnm
order by q0.rnm
update tab2
set tab2.amount=abc.PREV_AMOUNT
from
table2 tab2
join
(SELECT *,T2.AMOUNT PREV_AMOUNT
FROM TABLE1 T1
JOIN
(
SELECT
MAX(TIME) TIME,DATE,ITEM,MAX(AMOUNT) AMOUNT
FROM TABLE1
WHERE TIME!=(SELECT MAX(TIME) FROM TABLE1
GROUP BY DATE,ITEM)
GROUP BY DATE,ITEM) T2
ON T1.DATE=T2.DATE
AND T1.ITEM=T2.ITEM
AND T1.TIME=T2.TIME) abc
on tab2.date=abc.date
and tab2.item=abc.item
where tab2.new='Y' and tab2.amount is null
分解:找到每組日期和項目的第二個最長時間。 在日期和項目上加入原始table1的第二個最長時間以獲得將是prev的金額金額使用此prev金額根據日期和項目更新表2,無論new ='Y'
PS:我沒有在sql developer上運行此查詢。 但我用過的想法應該有效。
你可以嘗試這個......
UPDATE T SET T.Amount = ( SELECT MAX(T2.Amount) FROM table2 T2
WHERE T2.Amount IS NOT NULL AND T2.[time] <= T.[time] and T2.item = T.item and t2.[date]=T.[date]
) from table2 as T
WHERE T.Amount IS NULL
如果工作正常,請接受標記。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.