Difference of values that belong to same group but stored in two rows

别来无恙 提交于 2020-01-24 18:50:00

问题


I have a problem where i need to fetch 2 specific records with 2 different value and find the difference between their amount. This needs to be done for each device. Lets take the following table as example

DevID   reason    amount         DateTime
--------------------------------------------------
99       5        84       18-12-2016 18:10
99       0        35       18-12-2016 18:11
99       0        80       18-12-2016 18:12
99       0        34       18-12-2016 18:15
23       5        36       18-12-2016 18:16
23       4        22       18-12-2016 18:17
23       1        22       18-12-2016 18:18
23       2        22       18-12-2016 18:19
99       2        11       18-12-2016 18:20
99       8        50       18-12-2016 18:21
99       0        23       18-12-2016 18:22
99       5        06       18-12-2016 18:25
99       8        12       18-12-2016 18:30

So my reason of interest is 5 and 8. 5 is device logon and 8 is logout and other numbers refer to other things. I want to fetch records with device logon reason(5) and the next device logout(8) and find the difference in its amount value so in the table above for device 99, amount for reason 5 is 84 and the logout event(8) is 50, so the difference is 34 which if greater than 10 i need list that device. (please note there is another case of 5 and 8 for the same record, the difference is not greater than 5) but the first set has diff greater than 10 so we need to display that device id

So the expected output for the above is

DevID
-------
99

i was thinking of join Join table A which has all records with 5(sorted by deviceid,date) and table B which has all records of with 8 and then subtract their amounts and display the records with value greater than 10. Not sure if join is the way to go? any simpler/fast solution?


回答1:


You can use LEAD function to match logon time with logout:

WITH cte AS (
    SELECT devid
         , reason
         , amount
         , LEAD(reason) OVER (PARTITION BY devid ORDER BY datetime) AS next_reason
         , LEAD(amount) OVER (PARTITION BY devid ORDER BY datetime) AS next_amount
    FROM t
    WHERE reason IN (5, 8)
)
SELECT *, amount - next_amount AS diff
FROM cte
WHERE reason = 5               -- logon
AND next_reason = 8            -- next event is a logout
AND amount - next_amount >= 10 -- difference of current and next



回答2:


You can get the next "8" value using window functions. Then join and filter:

select t.*,
       (t.value - t8.value) as diff
from (select t.*,
             min(case when reason = 8 then datetime end) over (partition by devid order by datetime desc) as next_8_datetime
      from t
     ) t left join
     t t8
     on t8.devid = t.devid and
        t8.datetime = t.next_8_datetime and
        t8.reason = 8
where t.reason = 5
order by diff desc
limit 1;


来源:https://stackoverflow.com/questions/59071061/difference-of-values-that-belong-to-same-group-but-stored-in-two-rows

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