यह एप्लिकेशन स्तर पर बेहतर तरीके से किया जाता है, लेकिन केवल मनोरंजन के लिए, यहाँ यह डेटाबेस स्तर पर है:
select `user`, `start`, `stop`, diff from (
select
t.*
, if(@prev_user = `user`, (`stop` - @prev) * -1, 0) as diff
, @prev := `start`
, @prev_user := `user`
from
t
, (select @prev := null, @prev_user := null) var_init
order by `user`, `start` desc
) sq
order by `user`, `start`
- इसे एक sqlfiddle में लाइव काम करते हुए देखें
ध्यान दें, कि MySQL में कोई अंतराल/लीड फ़ंक्शन नहीं हैं। आप बस इतना कर सकते हैं, चर का उपयोग करना है। SELECT
खंड एक समय में एक पंक्ति संसाधित हो जाता है। तो आप SELECT
. की अंतिम पंक्तियों में वर्तमान पंक्ति का मान निर्दिष्ट कर सकते हैं खंड और इसलिए इस चर का उपयोग SELECT
की पहली पंक्तियों में "पिछली पंक्ति" के मान के रूप में करें खंड।
यह भी ध्यान दें, कि ORDER BY
बहूत ज़रूरी है। एक तालिका क्रमबद्ध नहीं है। एक रिलेशनल DBMS में डेटा तब तक सॉर्ट नहीं किया जाता जब तक कि आप ORDER BY
के साथ कोई ऑर्डर निर्दिष्ट नहीं करते हैं खंड।
- क्वेरी में वेरिएबल का उपयोग करने के बारे में अधिक पढ़ें यहां ए>
संपादित करें:
इसे बदलें
UPDATE inactivitytmp
JOIN (
SELECT
inactivitytmp.*
, if(@prev_user_id = `user_id`, (`end_ts` - @prev) * -1, 0) as diff2
, @prev := `start_ts`
, @prev_user_id := `user_id`
FROM
inactivitytmp
, (SELECT @prev := null, @prev_user_id := null) var_init
ORDER BY `user_id`, `start_ts` DESC
) query_alias
ON inactivitytmp.user_id=query_alias.user_id AND inactivitytmp.start_ts=q uery_alias.start_ts AND inactivitytmp.end_ts=query_alias.end_ts
SET inactivitytmp.diff=query_alias.diff2;