SQL Server MSSQL中不使用循环比较前一行值和当前行值

fnvucqvd  于 2023-01-01  发布在  其他
关注(0)|答案(2)|浏览(140)
    • 源表**

| 行号|旗帜|币种_值|先前值|
| - ------| - ------| - ------| - ------|
| 1个|C级|第1版|零|
| 第二章|P级|V11|零|
| 三个|P级|V12|零|
| 四个|C级|第2版|零|
| 五个|C级|V31|零|
| 六个|P级|三十二|零|
我有一个场景,我必须比较前一行的值和当前行的值,并根据case条件更新Curr_value列,并且应该为表中的所有记录导出curr_value和Prev_value。
用于导出Curr_value列的条件是case when(Flag ='C ')then curr_value else Prev_value end,并且我使用MSSQL中的LAG函数来获取Previous value列。

    • 输出**

| 行号|旗帜|币种_值|先前值|
| - ------| - ------| - ------| - ------|
| 1个|C级|第1版|无|
| 第二章|P级|第1版|第1版|
| 三个|P级|第1版|第1版|
| 四个|C级|第2版|第1版|
| 五个|C级|第3版|第2版|
| 六个|P级|第3版|第3版|
我试着用While循环实现同样的效果,但是执行时间非常长。请告诉我在MSSQL中不使用循环是否可以实现同样的输出。

siotufzp

siotufzp1#

我设置了以下脚本作为完整的工作示例:

CREATE TABLE #tmpSampleData(
    Row_no int NOT NULL PRIMARY KEY  
    ,Flag varchar(1) NULL
    ,Curr_value varchar(3) NULL 
); 

INSERT INTO #tmpSampleData (Row_no,Flag,Curr_value) 
VALUES (1, 'C', 'V1')
,(2, 'P', 'V1')
,(3, 'P', 'V1')
,(4, 'C', 'V2')
,(5, 'C', 'V3')
,(6, 'P', 'V3'); 

SELECT 
    sample_data.Row_no
    ,sample_data.Flag
    ,sample_data.Curr_value
    ,LAG(sample_data.Curr_value,1,'0') OVER(ORDER BY sample_data.Row_no) AS Prev_value
    ,CASE 
        WHEN sample_data.Flag = 'C'
            THEN sample_data.Curr_value
        ELSE LAG(sample_data.Curr_value,1,'0') OVER(ORDER BY sample_data.Row_no)
    END AS CalculatedField
FROM 
    #tmpSampleData AS sample_data; 

IF OBJECT_ID(N'tempdb..#tmpSampleData', N'U') IS NOT NULL 
BEGIN 
    DROP TABLE #tmpSampleData; 
END;

但我认为你感兴趣的主要部分是:

CASE 
    WHEN sample_data.Flag = 'C'
        THEN sample_data.Curr_value
    ELSE LAG(sample_data.Curr_value,1,'0') OVER(ORDER BY sample_data.Row_no)
END AS CalculatedField

只需添加sample_data.Flag = 'C'的条件,然后返回Curr_value或'LAG的结果

yrdbyhpb

yrdbyhpb2#

只需使用滞后功能...

Create table #temp
(
id int,
Fuel int,
dates date
)

Insert into #temp values(1,10,getdate())
Insert into #temp values(2,5,getdate()+1)
Insert into #temp values(3,18,getdate()+2)
Insert into #temp values(4,10,getdate()+3)
Insert into #temp values(5,8,getdate()+4)
Insert into #temp values(6,20,getdate()+5)
Insert into #temp values(7,10,getdate()+6)

Select * from (
SELECT id,
    LAG(Fuel, 1) OVER (ORDER BY id ASC) AS previous_Fuel , Fuel, dates
FROM #temp )A where Isnull(previous_Fuel,0) < Fuel

相关问题