code up

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

並んでる順にgroup by

説明するのが難しいのですが、group byをした時に結果全体に対してgroup byするのではなく、出現した順にまとめたい。つまりA, A, B, A, CとあったらA, B, A, Cとなって欲しい。そんな要件がありました。

Oracleであればlag, leadを使えば実現できるみたいですが、MySQLにはその関数がないため一工夫必要そう。自力で考える力が無いため、stackoverflowに助けて頂いた。

まずはサンプルのテーブル。

フィールド名
id int
val char(1)
date int

投入したデータ。

id val date
1 A 1
1 A 2
1 B 3
1 B 4
1 A 5
1 A 6
1 C 7
2 A 8
2 A 9
2 B 10
2 B 11
2 A 12
2 A 13
2 C 14

流したSQL。

select
	id,
	val,
	count(*)
from
	(
		select
			id,
			val,
			(
				case when @v != val then
					@i := @i+1
				else
					@i
				end
			) gid,
			@v := val
		from
			sample,
			(
				select
					@v := '',
					@i := 0
			) vars
		order by
			id,
			date
	) tbl
group by
	id,
	val,
	gid
;

結果。

id val count(*)
1 A 2
1 B 2
1 A 2
1 C 1
2 A 2
2 B 2
2 A 2
2 C 1

キチンと指定した並び順でグループ化された。

少し補足をしておくと、

  • まず実体のテーブルに変数を持つ副問合せをくっつける。(vars)
  • このvarsの値は各行として実体化する際、前行の値と比較し(@v != val)異なる場合に数値(@i)を増分させる(=gid)。
  • 上記クエリーを副問合せ(tbl)にし、実体テーブルのグループ化したい項目と上記増分値(gid)を合わせgroup byしている。
関連記事
タグ:MySQL SQL
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。