Last time value changed from negative to positive

ぐ巨炮叔叔 提交于 2020-02-28 07:04:50

问题


How can you return the date by PersonID when the last time the Balance field went from a negative value to a positive value?

In the sample data below, for PersonID 1 it happened for 8th July 2019, for PersonID 2 it happened for 8th August 2019. There can be multiple times the value changes from negative to positive but it should only reference the latest time it happens.

Expected Output:

I have the below sample data

Create Table #temp
(
    PersonID int,
    ActionDate date,
    Balance money
)
insert into #temp
(
    PersonID,
    ActionDate,
    Balance
)
select
    1,
    '01 Jul 2019',
    -100
union all
select
    1,
    '02 Jul 2019',
    -45
union all
select
    1,
    '03 Jul 2019',
    -80
union all
select
    1,
    '04 Jul 2019',
    -20
union all
select
    1,
    '05 Jul 2019',
    40
union all
select
    1,
    '06 Jul 2019',
    -40
union all
select
    1,
    '07 Jul 2019',
    -90
union all
select
    1,
    '08 Jul 2019',
    -150
union all
select
    1,
    '09 Jul 2019',
    100
union all
select
    1,
    '10 Jul 2019',
    120
union all
select
    1,
    '11 Jul 2019',
    130
union all
select
    1,
    '12 Jul 2019',
    140
--
union all
select
    2,
    '01 Aug 2019',
    -100
union all
select
    2,
    '02 Aug 2019',
    -45
union all
select
    2,
    '03 Aug 2019',
    80
union all
select
    2,
    '04 Aug 2019',
    20
union all
select
    2,
    '05 Aug 2019',
    -40
union all
select
    2,
    '06 Aug 2019',
    -40
union all
select
    2,
    '07 Aug 2019',
    40
union all
select
    2,
    '08 Aug 2019',
    -40
union all
select
    2,
    '09 Aug 2019',
    45
union all
select
    2,
    '10 Aug 2019',
    65
union all
select
    2,
    '11 Aug 2019',
    23
union all
select
    2,
    '12 Aug 2019',
    105

回答1:


This might do what you want using not exists. It finds the last negative balance:

select t.*
from #temp t
where t.balance < 0 and
      not exists (select 1
                  from #temp t2
                  where t2.personid = t.personid and
                        t2.actiondate > t.actiondate and
                        t2.balance < 0
                 );

If you want the last change, you can filter using window functions:

select t.*
from (select t.*,
             row_number() over (partition by personid order by actiondate desc) as seqnum
      from (select t.*,
                   lead(balance) over (partition by personid order by actiondate) as next_balance
            from #temp t
           ) t
      where t.balance < 0 and
            t.next_balance > 0
     ) t
where seqnum = 1;


来源:https://stackoverflow.com/questions/57582657/last-time-value-changed-from-negative-to-positive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!