इसे आजमाएं:
;with cte as
(select *,
coalesce(row_index - (lag(row_index) over (order by event)),1) diff
from tbl
),
cte2 as
(select *,
(select max(diff)
from cte c
where c.row_index <= d.row_index
) minri
from cte d
)
select event, row_index, minri,
dense_rank() over (order by minri) rn
from cte2
- पहले सीटीई को
lag
का उपयोग करके अंतर मिलता है फ़ंक्शन (एसक्यूएल सर्वर 2012 के बाद से उपलब्ध)। - अगला सीटीई गणना करता है जब अंतर 1 से अधिक हो जाता है और उस बिंदु के बाद सभी रिकॉर्ड 'समूह' को असाइन करता है, जब तक कि अगला अंतर <> 1 नहीं मिलता है। समूहीकरण में यह महत्वपूर्ण कदम है।
- अंतिम चरण
dense_rank
का उपयोग करना है आवश्यकता के अनुसार पंक्ति संख्या प्राप्त करने के लिए पिछले चरण में गणना किए गए संकेतक से अधिक।
इस समाधान की एक सीमा है इसमें यह विफल हो जाएगा यदि अंतर बढ़ते क्रम में नहीं हैं यानी यदि आपके पास नमूना डेटा में दो और मान हैं जैसे कि 52 और 53, तो यह उन्हें एक नया समूह बनाने के बजाय समूह 3 में वर्गीकृत करेगा।
अपडेट करें :नीचे दिया गया दृष्टिकोण उपरोक्त सीमा को पार कर सकता है:
;with cte as
(select *,
coalesce(row_index - (lag(row_index) over (order by event)),1) diff
from tbl)
,cte2 as
(select *,
diff - coalesce(diff - (lag(diff) over (order by event)),0) tmp
from cte d)
select event,row_index,
1 + sum(case when tmp >= diff then 0 else 1 end) over (order by event) risum
from cte2
फिर पहला कदम वही रहता है। लेकिन चरण 2 में, हम केवल न्यूनतम/अधिकतम फ़ंक्शन का उपयोग करने के बजाय, क्रमिक मानों के बीच अंतर के भिन्न मान पर संक्रमण के लिए जाँच करते हैं। रैंकिंग तब मूल डेटा में प्रत्येक मान के लिए एक समूह निर्दिष्ट करने के लिए एक सशर्त योग का उपयोग करती है।
इसे और सरल बनाया जा सकता है:
select event, row_index,
sum(case when diff <= 1 then 0 else 1 end) over (order by event) as rb
from
(select *,
row_index - (lag(row_index) over (order by event)) diff
from tbl
) s