おけらのブログ++

駆け出しWebエンジニアの奮闘記

RailsのDBから登録数の多い順にソートして取得する方法

Railsのデータベース操作がまだまだ未熟なため、簡単なことですがメモしておきます。
今回はデータベースに登録されている情報から、あるカラムに注目し多い順にソートしてインスタンスを取得する方法についてまとめます。

前置き

イメージを湧きやすくするために作成中のサービスについて説明します。

今作っている機能で、ユーザーがCDを検索して気に入ったものがあれば、お気に入り登録をするという機能があります。
その時のデータベースのリレーションはこのようになっています。

User n ----- 1 中間テーブル 1 ------ n Album

そして今回ソート対象の中間テーブルをMysqlで見ると下記のようになっています。
f:id:Okerra:20180304153057p:plain
複数のユーザーがどのアルバムを登録したかの紐付け表となっています。

このデータベースから登録数の多い順に、アルバム情報を取得する方法を検討します。

GROUP BY と ORDER と COUNT

登録数の多い順に表示するのは難しいことはなく、GROUP BYとORDER、COUNTを使えばできます。今回はその中でもトップページにTOP1位のアルバムを表示したかったためFirstを使っていますが、付けなければ重複をなくし、多い順にソートした全インスタンスを取得できます。

class ToppagesController < ApplicationController
  def index
    @topArt = RelationAlbum.group(:album_id).order("count(album_id) desc").first;
    @album  = Album.find(@topArt.album_id)
  end
end

これをControllerに記述した時に、実際に実行されるSQL文もrails cを使って見てみます。
firstなしの場合

SELECT `relation_albums`.* FROM `relation_albums` GROUP BY `relation_albums`.`album_id` ORDER BY count(album_id) desc

firstありの場合

SELECT `relation_albums`.* FROM `relation_albums` GROUP BY `relation_albums`.`album_id` ORDER BY count(album_id) desc  LIMIT 1

ちなみに知りませんでしたが、firstをつければLIMITというSQL文が付け加えられるようです。今までControllerが上手くやってくれていましたが、たまにはrails cで実行されるSQL文を見ると結構勉強になります!

そして4月のTechAcademyコンテストで絶対に勝ちたいので、これから頑張ります。
(過去のコンテストの優秀賞の作品のレベルが高いのでビビってます...)