【最新記事】⇒仮公開開始(2019/02/07)

重複行の話

同一アビリティでレベルによって更新されるものがあるが、検索結果にはHitするもの全てを表示するようにしている。しかしデータが増えてくると、バリエーションが多い(といっても、最大で3だが)アビリティは少々うざくなる。行数制限なども必要になってくるので、同じアビリティに関しては1行で表示するオプションが必要なのは承知していた。(そのつもりでチェックボックスは既に用意してあった)

SQLで重複行をまとめるのであれば「DISTINCT」しかないだろう。

SELECT COUNT(DISTINCT detail.ab_id) FROM ab_detail_tbl detail

こうかけば、重複しているIDはまとめられて1行としてカウントされる。では、実際のデータのSELECTはどうするか?

SELECT DISTINCT detail.ab_id, detail.ab_name, detail.ab_type
FROM ab_detail_tbl detail

こんな感じに通常だとなるのだが、同じidなら当然名前も同じなのでいいのだけれど、タイプによってレコードを分けている関係上これは意図した通りにまとまらない。つまり、ab_typeが同一ab_idで複数存在した場合にまとめる事ができない。

PostgreSQLの場合にはこれは次のように書けるらしい。

SELECT DISTINCT ON(detail.ab_id), detail.ab_name, detail.ab_type
FROM ab_detail_tbl detail

しかしながら、残念な事のMySQLではこれは採用されていないようだ。ではどうするか。サブクエリを発行してそこから重複ID分を除くという手段もあるようだったが、GROUP BYが使えるような感じだった。次のような感じ。

SELECT detail.ab_id, detail.ab_name, detail.ab_type
FROM ab_detail_tbl detail GROUP BY detail.ab_id

試してみると、意図通りにCOUNTと同じくIDだけに着目した重複のまとめが実現できた。DISTINCTじゃなく、GROUP BYだと実際SELECTされてからキャッシュ内でまとめ処理が走るような気がするので、性能的な懸念はあるのだが、それはサブクエリとそんなに差は無いのではないだろうか?そして、そもそも大量データになる場合はカウントで除外するようになっているので、致命的な性能劣化はおきないのでは?と考えている(というか期待している)。

テストはこれで実施してみよう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

アップロードファイルの最大サイズ: 1 MB。 画像 をアップロードできます。 ここにファイルをドロップ