आपकी क्वेरी में बदलने के लिए बहुत कुछ नहीं है। आपको मूल रूप से name
. का चयन करना होगा और number
सबक्वेरी में और उसी क्रम में क्रमबद्ध करें। फिर आप name, number - rn
. के आधार पर ग्रुप बना सकते हैं बाहरी क्वेरी में।
SELECT
min(number) first_number,
max(number) last_number,
count(*) AS no_records,
name
FROM (
SELECT c.*, @rn := @rn + 1 rn
from (
SELECT name, number
FROM `table`
WHERE cc = 1
ORDER BY name, number
LIMIT 99999999999999999
) AS c
CROSS JOIN (SELECT @rn := 0) r
) c
GROUP BY name, number - rn
ORDER BY first_number ASC, name ASC;
परिणाम:
first_number last_number no_records name
1 2 2 Apple
3 3 1 Bean
10 12 3 Hello
14 14 1 Deer
14 14 1 Door
15 15 1 Hello
17 17 1 Hello
मैं आमतौर पर इस तरह से सत्र चर के उपयोग के खिलाफ वकालत करता हूं। कारण यह है कि इस तरह के समाधान आंतरिक कार्यान्वयन पर निर्भर करते हैं, और संस्करण अपडेट या सेटिंग्स में बदलाव से तोड़े जा सकते हैं। उदाहरण के लिए:एक बार मारियाडीबी ने बिना LIMIT के सबक्वायरी में ORDER BY क्लॉज को नजरअंदाज करने का फैसला किया। यही कारण है कि मैंने एक विशाल सीमा शामिल की है।
मैंने number
. को भी बदल दिया है first_number
. के साथ ONLY_FULL_GROUP_BY मोड में समस्याओं से बचने के लिए बाहरी ORDER BY क्लॉज में।
अस्थायी तालिका में AOTO_INCREMENT कॉलम का उपयोग करना पंक्ति संख्या उत्पन्न करने का एक अधिक स्थिर तरीका है:
drop temporary table if exists tmp_tbl;
create temporary table tmp_tbl (
rn int unsigned auto_increment primary key,
name varchar(64) not null,
number int not null
);
insert into tmp_tbl (name, number)
select name, number
from `table`
order by name, number;
अंतिम चयन क्वेरी उपरोक्त बाहरी क्वेरी के समान है:
SELECT
min(number) first_number,
max(number) last_number,
count(*) AS no_records,
name
FROM tmp_tbl
GROUP BY name, number - rn
ORDER BY first_number ASC, name ASC;
अधिक हाल के संस्करण में (मारियाडीबी 10.2 से शुरू) आप ROW_NUMBER()
का उपयोग कर सकते हैं इसके बजाय विंडो फ़ंक्शन:
SELECT
min(number) first_number,
max(number) last_number,
count(*) AS no_records,
name
FROM (
SELECT
name,
number,
row_number() OVER (ORDER BY name, number) as rn
FROM `table`
WHERE cc = 1
) c
GROUP BY name, number - rn
ORDER BY first_number ASC, name ASC;