आप CTE
में लिपटी निम्न क्वेरी का उपयोग कर सकते हैं आपके अनुक्रम में निहित मानों को क्रम संख्या निर्दिष्ट करने के लिए:
;WITH Seq AS (
SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn
FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k,v)
)
आउटपुट:
v rn
-------
5 1
9 2
6 3
उपरोक्त CTE
का उपयोग करना आप द्वीपों की पहचान कर सकते हैं, यानी अनुक्रमिक पंक्तियों के स्लाइस जिनमें संपूर्ण अनुक्रम शामिल है:
;WITH Seq AS (
SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn
FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k,v)
), Grp AS (
SELECT [Key], [Value],
ROW_NUMBER() OVER (ORDER BY [Key]) - rn AS grp
FROM mytable AS m
LEFT JOIN Seq AS s ON m.Value = s.v
)
SELECT *
FROM Grp
आउटपुट:
Key Value grp
-----------------
1 5 0
2 9 0
3 6 0
6 5 3
7 9 3
8 6 3
grp
फ़ील्ड आपको वास्तव में इन द्वीपों की पहचान करने में मदद करता है।
अब आपको केवल आंशिक समूहों को फ़िल्टर करना है:
;WITH Seq AS (
SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn
FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k,v)
), Grp AS (
SELECT [Key], [Value],
ROW_NUMBER() OVER (ORDER BY [Key]) - rn AS grp
FROM mytable AS m
LEFT JOIN Seq AS s ON m.Value = s.v
)
SELECT g1.[Key], g1.[Value]
FROM Grp AS g1
INNER JOIN (
SELECT grp
FROM Grp
GROUP BY grp
HAVING COUNT(*) = 3 ) AS g2
ON g1.grp = g2.grp
नोट: इस उत्तर के प्रारंभिक संस्करण में INNER JOIN
. का उपयोग किया गया था करने के लिए Seq
. यदि तालिका में 5, 42, 9, 6
. जैसे मान हैं तो यह काम नहीं करेगा , 42
. के रूप में INNER JOIN
. द्वारा फ़िल्टर कर दिया जाएगा और इस क्रम को गलत तरीके से वैध के रूप में पहचाना गया। इस संपादन का श्रेय @HABO को जाता है।