我有一个具有以下布局和值的表
我希望根据以下规则更新“ PrevMonthly Amount”列的数据
对于REFNO和KEY的组合,
最终预期结果将是
我尝试在SQL中使用LAG函数,但没有得到如上所示的预期结果。
SELECT REFNO, KEY, SEQNO,
LAG(DATE,1) OVER (PARTITION BY REFNO, KEY ORDER BY REFNO, KEY, SEQNO) as DATE_Prev
INTO #TEMP_TABLE
FROM MainTable
UPDATE A SET
A.PrevMonthlyAmount = CASE WHEN A.DATE <> B.DATE_Prev
THEN A.PrevAmount ELSE A.PrevMonthlyAmount END
FROM MainTable A
JOIN #Temp_Table B
ON A.REFNO = B.REFNO And A.KEY = B.KEY And A.SEQNO = B.SEQNO
UPDATE A SET
A.PrevMonthlyAmount = CASE WHEN A.DATE = B.DATE_PREV
THEN (SELECT PrevMonthlyAmount From STAGE_LARGE_BANDED Where SEQNO = A.SEQNO - 1 And REFNO = A.REFNO And KEY = A.KEY AND)
ELSE A.PrevMonthlyAmount END
FROM MainTable A
JOIN #Temp_Table B
ON A.REFNO = B.REFNO And A.KEY = B.KEY And A.SEQNO = B.SEQNO
我在表布局中指示的数据集只是一个示例,并且正在处理的表中,在实时情况下,该表将具有近几百万行。
查询得到的结果如下
创建表和插入查询如下,
CREATE TABLE [dbo].[MAINTABLE](
[REFNO] [int] NULL,
[KEY] [Int] NULL,
[SEQNO] [int] NULL,
[DATE] [int] NULL,
[AMOUNT] [int] NULL,
[PrevAMOUNT] [int] NULL,
[PrevMonthlyAmount] [int] NULL,
)
INSERT INTO MAINTABLE Values(1000000,2,1,201801,100,0,0)
INSERT INTO MAINTABLE Values(1000000,2,2,201801,200,100,0)
INSERT INTO MAINTABLE Values(1000000,2,3,201802,300,200,0)
INSERT INTO MAINTABLE Values(1000000,2,4,201802,400,300,0)
INSERT INTO MAINTABLE Values(1000000,2,5,201802,420,400,0)
INSERT INTO MAINTABLE Values(1000000,2,6,201803,450,400,0)
INSERT INTO MAINTABLE Values(2000000,1,1,201801,150,0,0)
INSERT INTO MAINTABLE Values(2000000,1,2,201801,250,150,0)
INSERT INTO MAINTABLE Values(2000000,1,3,201801,350,250,0)
INSERT INTO MAINTABLE Values(3000000,1,1,201801,175,0,0)
INSERT INTO MAINTABLE Values(3000000,1,2,201802,275,175,0)
INSERT INTO MAINTABLE Values(3000000,1,3,201803,375,275,0)
答案 0 :(得分:2)
您可以apply
:
select t.*, t1.prevmonthly_amount
from table t outer apply
(select top (1) t1.amount as prevmonthly_amount
from table t1
where t.refno = t1.refno and t.key = t1.key and
t1.date < t.date
order by t1.seqno desc
) t1;
答案 1 :(得分:1)
嗯。 。 。前一个月的金额似乎是该月的第一个值。因此,我认为这适用于您的数据:
select t.*,
first_value(prevamount) over (partition by refno, key, date order by seqno) as prevmonthly_amount
from t;
Here是db <>小提琴。
答案 2 :(得分:0)
非常感谢您的所有时间和投入。
我尝试了一些解决问题的方法,并找到了解决方案!!!
但是我绝对相信,总有比这更好的解决方案...:):)
请参见下文
CREATE TABLE [dbo].[MAINTABLE](
[REFNO] [int] NULL,
[KEY] [int] NULL,
[SEQNO] [int] NULL,
[DATE] [int] NULL,
[AMOUNT] [int] NULL,
[PrevAMOUNT] [int] NULL,
[PrevMonthlyAmount] [int] NULL
) ON [PRIMARY]
Truncate Table MAINTABLE
INSERT INTO MAINTABLE Values(1000000,2,1,201801,100,0,0)
INSERT INTO MAINTABLE Values(1000000,2,2,201801,200,100,0)
INSERT INTO MAINTABLE Values(1000000,2,3,201802,300,200,0)
INSERT INTO MAINTABLE Values(1000000,2,4,201802,400,300,0)
INSERT INTO MAINTABLE Values(1000000,2,5,201802,420,400,0)
INSERT INTO MAINTABLE Values(1000000,2,6,201803,450,420,0)
INSERT INTO MAINTABLE Values(2000000,1,1,201801,150,0,0)
INSERT INTO MAINTABLE Values(2000000,1,2,201801,250,150,0)
INSERT INTO MAINTABLE Values(2000000,1,3,201801,350,250,0)
INSERT INTO MAINTABLE Values(3000000,1,1,201801,175,0,0)
INSERT INTO MAINTABLE Values(3000000,1,2,201802,275,175,0)
INSERT INTO MAINTABLE Values(3000000,1,3,201803,375,275,0)
SELECT REFNO, [KEY], SEQNO,
LAG(DATE,1) OVER (PARTITION BY REFNO, [KEY] ORDER BY REFNO, [KEY], SEQNO) as DATE_Prev
INTO #TEMP_TABLE
FROM MainTable
UPDATE A SET
A.PrevMonthlyAmount =
CASE WHEN A.DATE <> B.DATE_Prev
THEN A.PrevAmount
ELSE A.PrevMonthlyAmount
END
FROM MainTable A
JOIN #Temp_Table B
ON A.REFNO = B.REFNO And A.[KEY] = B.[KEY] And A.SEQNO = B.SEQNO
SELECT A.*
INTO #TEMP_TABLE2
FROM MAINTABLE A
JOIN (SELECT REFNO, [KEY], [DATE], MIN(SEQNO) as FirstTransId From MAINTABLE
GROUP BY REFNO, [KEY], [DATE]) B
ON A.REFNO = B.REFNO And A.[KEY] = B.[KEY] And A.[DATE] = B.[DATE] And A.SEQNO = B.FirstTransId
UPDATE A SET
A.PrevMonthlyAmount = B.PrevMonthlyAmount
FROM MainTable A
JOIN #TEMP_TABLE2 B
ON A.REFNO = B.REFNO And A.[KEY] = B.[KEY] And A.[DATE] = B.[DATE]
Where A.SEQNO <> B.SEQNO
Select * from MAINTABLE