【问题标题】:sql sum partition over two columns两列的sql sum分区
【发布时间】:2020-04-25 14:12:51
【问题描述】:

我有下表

--------------------------------------------------------
|  sell | sell_code| buy   | buy_code|   date_time     |
--------------------------------------------------------
|  100  |   usd   |  150   |  eur    |  20/10/2020 09:20
|  50   |   gbp   |  114   |  eur    |  20/10/2020 11:20
|  80   |   eur   |  null  |  null   |  20/10/2020 15:40
|  null |   null  |  80    |  usd    |  21/10/2020 09:20
|  100  |   usd   |  80    |  gbp    |  21/10/2020 13:30
--------------------------------------------------------

我想在代码相同时按卖出和买入列对分区求和,卖出金额为“+”,买入金额为“-”

想要这样的结果(mssql 2008+)

-----------------------------------------------------------------------------------
|sell|sell_code| buy |buy_code|date_time       ||balance1|b_code1|balance2|b_code2|
-----------------------------------------------------------------------------------
|100 |  usd   |  150 | eur    |20/10/2020 09:20||    100 | usd   |-150    | eur   |
|50  |  gbp   |  114 | eur    |20/10/2020 15:40||     50 | gbp   |-264    | eur   |
|80  |  eur   |  null| null   |20/10/2020 15:40||   -184 | eur   | null   | null  |  
|null|  null  |  80  | usd    |21/10/2020 09:20||   null | null  |  20    | usd   |
|100 |  usd   |  80  | gbp    |21/10/2020 13:30||    120 |  usd  | -30    | gbp   |
-----------------------------------------------------------------------------------

这样计算

-----------------------------------------------------------------------------------------------------
|  sell | sell_code| buy   | buy_code|   date_time     |||balance1       |b_code1|balance2  |b_code2|
-----------------------------------------------------------------------------------------------------
|  100  |   usd   |  150   |  eur    |  20/10/2020 09:20||    100       | usd   |-150       | eur   |
|  50   |   gbp   |  114   |  eur    |  20/10/2020 11:20||     50       | gbp   |(-150)-114 | eur   |
|  80   |   eur   |  null  |  null   |  20/10/2020 15:40||(-150-114)+80 | eur   | null      | null  |  
|  null |   null  |  80    |  usd    |  21/10/2020 09:20||   null       | null  |(100)-80   | usd   |
|  100  |   usd   |  80    |  gbp    |  21/10/2020 13:30||(100-80)+100  | usd   | (50)-80   | gbp   |
-----------------------------------------------------------------------------------------------------

有什么想法吗?

【问题讨论】:

  • 取决于您拥有的 RDMS。在您的问题中注明(包括版本)
  • 请解释计算。它们并不明显。

标签: sql sql-server


【解决方案1】:

我认为您的代码没有处理join 中的NULLs。我稍微修改了你的代码如下:

select c.sell,c.sell_code,c.buy,c.buy_code,c.date_time, b.balance as balance1,b.code, b2.balance balance2, b2.code 
from
MyTable c
left join
(
    select sum(balance) over(partition by code order by convert(datetime, date_time, 104)) as balance,code,date_time 
    from
    (   select sell as balance,sell_code as code,date_time  from MyTable
        union all
        select 0-buy as balance,buy_code as code,date_time  from MyTable
    )a
)b
on isnull(b.code, '')=isnull(c.sell_code, '') and b.date_time=c.date_time 
left join
(
    select sum(balance) over(partition by code order by convert(datetime, date_time, 104)) as balance,code,date_time 
    from
    (   select sell as balance,sell_code as code,date_time  from MyTable
        union all
        select 0-buy as balance,buy_code as code,date_time  from MyTable
    )a
)b2
on isnull(b2.code, '')=isnull(c.buy_code, '') and b2.date_time=c.date_time 
order by convert(datetime, c.date_time, 104)

db小提琴demo

【讨论】:

  • @zuluman 您将答案代码复制到您的问题中,它没有给出预期的结果吗?
【解决方案2】:

经过长时间的努力,我用这种方法解决了

select sell,sell_code,buy,buy_code,a.date_time,balance1,bcode1,balance2,bcode2 from
(select * from @t)a
left join
(select sum(balance)over (partition by code order by date_time) as balance1,code as bcode1,date_time from
(select sell as balance,sell_code as code,date_time  from @t
union all
select 0-buy as balance,buy_code as code,date_time  from @t)x)b
on b.date_time=a.date_time and a.sell_code=b.bcode1
left join
(select sum(balance)over (partition by code order by date_time) as balance2,code as bcode2,date_time from
(select sell as balance,sell_code as code,date_time  from @t
union all
select 0-buy as balance,buy_code as code,date_time  from @t)x)c
on c.date_time=a.date_time and a.buy_code=c.bcode2

demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-07
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 2020-08-03
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多