问题
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