更新表记录将一个字段设置为有条件地在两行中添加字段

时间:2019-06-06 18:39:18

标签: sql sql-server

表名:TraderCapital

列:

Trader (varchar),   
Currency(varchar),   
Date(int i.e. yyyymmdd format),    
Capital(int)  

主要关键字段:交易者,货币

Trader, Currency, Date, Capital  
A, USD, 20190605, 100  
A, USD, 20190606, 100  
B, INR, 20190605, 200   
B, INR, 20190606, 200   
C, USD, 20190606, 100  
D, USD, 20190601, 100    

我想在将Capital 20190606汇总为Capital 20190605之后更新表格。因此,所需的输出应如下所示:

Trader, Currency, Date, Capital  
A, USD, 20190605, 200  
B, INR, 20190605, 400  
C, USD, 20190606, 100 
D, USD, 20190601, 100  

您能帮我写同样的sql查询吗?

3 个答案:

答案 0 :(得分:1)

您可以使用LAG()来实现。在第一步中,我创建了一个列,用于检查是否有前一天的行。稍后,我使用此列(previousDay)对行进行分组。

with previousDay as (
    select
        *
        ,LAG(date) over (partition by trader, currency order by date asc) as PreviousDay
    from TraderCapital
)
select
     trader
    ,currency
    ,case when PreviousDay is not null then dateadd(day, -1, date) else date end as date
    ,sum(Capital) as capital
from previousDay 
group by case when PreviousDay is not null then dateadd(day, -1, date) else date end
    ,trader
    ,currency

答案 1 :(得分:1)

尝试如下窗口功能:

select b.Trader,b.Currency, b.Date, b.running_total as Capital 
from (
select a.Trader,a.Currency, a.Date, a.running_total
, row_number() over (partition by a.Trader, a.Currency order by a.running_total desc) rnk
from (
select * ,sum(capital) over (partition by Trader, Currency order by Date desc) as running_total
from TraderCapital )a )b
where b.rnk = 1

测试结果:

Dd<>Fiddle

答案 2 :(得分:0)

感谢@M。 Kanarkowski和@Gen Wan的回答。根据您的建议,这是对我最终有效的方法:

with PreviousDayTable as (  
select *, LAG(Date) over (partition by Trader, Currency order by Date) 
          as previousDay
from TraderCapital
),
TotalTable as (
select Trader, Currency, 
       case when previousDay is not null then previousDay else Date end as PreviousDay,
       sum(Capital) as agg
  from PreviousDayTable 
  group by Trader, Currency,
           case when previousDay is not null then previousDay else Date end
)
update TraderCapital 
set TraderCapital.Capital = B.agg
from TraderCapital as A JOIN TotalTable as B
ON A.Trader = B.Trader
AND A.Currency = B.Currency
AND A.Date = B.previousDay


with PreviousDayTable as (
select *, LAG(Date) over (partition by Trader, Currency order by Date) 
          as previousDay
from TraderCapital
)
delete A
from TraderCapital as A JOIN PreviousDayTable as B
ON A.Trader = B.Trader
AND A.Currency = B.Currency
AND A.Date = B.Date
where B.previousDay is not null

随时提出改进建议。