クエリに変更を加えることはあまりありません。基本的に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
私は通常、このようなセッション変数の使用に反対することを提唱しています。その理由は、そのようなソリューションは内部実装に依存しており、バージョンの更新や設定の変更によって機能しなくなる可能性があるためです。例:MariaDBがLIMITなしのサブクエリでORDERBY句を無視することを決定した場合。これが、私が巨大な制限を含めた理由です。
number
も置き換えました first_number
を使用 ONLY_FULL_GROUP_BYモードの問題を回避するために、外側のORDERBY句で。
行番号を生成するためのより安定した方法は、一時テーブルで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クエリは、上記の外部クエリと同じです。
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;
より新しいバージョン(MariaDB 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;