1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsのdistinctメソッドについて。(SQL練習①)

Posted at

背景

  • Railsで検索フォームを作っています
  • お手本のコードに読み慣れないメソッドがいっぱい&SQL自体慣れていないので、勉強しながらノートにまとめてみました

▼環境

  • Rails 5.2.3
  • Ruby 2.6.0

なお、本記事は下記の記事の内容を自分の環境で試しながら、知見をまとめたものです。

Rails distinctメソッドについて

distinctメソッド

distinctメソッドは、レコードを一位にまとめてくれるメソッドです。APIドキュメントはこちら。

例えば、UserPostを投稿するアプリにおいて、

> Post.select(:user_id)

とすると、

Post Load (1.2ms)  SELECT `posts`.`user_id` FROM `posts`
=> [#<Post:0x00007f826d51c290 id: nil, user_id: 1>,
 #<Post:0x00007f826d51c150 id: nil, user_id: 1>,
 #<Post:0x00007f826d51c010 id: nil, user_id: 2>,
 #<Post:0x00007f826d527e88 id: nil, user_id: 2>,
 #<Post:0x00007f826d527d48 id: nil, user_id: 3>,
 #<Post:0x00007f826d527c08 id: nil, user_id: 4>,
 #<Post:0x00007f826d527ac8 id: nil, user_id: 5>,
 #<Post:0x00007f826d527988 id: nil, user_id: 5>]

と出てきます。これにdistinctを加えると

> Post.select(:user_id).distinct
  Post Load (1.6ms)  SELECT DISTINCT `posts`.`user_id` FROM `posts`
=> [#<Post:0x00007f8268b1f8e0 id: nil, user_id: 1>,
 #<Post:0x00007f826d51c010 id: nil, user_id: 2>,
 #<Post:0x00007f826d527d48 id: nil, user_id: 3>,
 #<Post:0x00007f826d527c08 id: nil, user_id: 4>,
 #<Post:0x00007f826d527988 id: nil, user_id: 5>]

と、投稿がselectで選択した項目によって一意になります。ちなみに、先の記事にもありますが。selectと一緒に使わないと、全てのpostをとってきます。

> Post.distinct(:user_id)
SELECT DISTINCT `posts`.* FROM `posts`
/* 全てのpostが表示される */

発行されるSQLを見比べればわかるのですが、

/* selectがある時 */
> Post.select(:user_id).distinct
Post Load (1.6ms)  SELECT DISTINCT `posts`.`user_id` FROM `posts`

/* selectがない時 */
> Post.distinct(:user_id)
SELECT DISTINCT `posts`.* FROM `posts`

selectがないと、全てのカラムを持ってきて、それらについて一意の値を呼び出してくるのですね。
逆に「重複する投稿を表示しない」などでしたら、シンプルに

> Post.distinct
SELECT DISTINCT `posts`.* FROM `posts`

で良さそうです。

なお、親子関係のあるレコード(例えばpostのコメント)に関しては、

> post = Post.first
> post.comments.select(:user_id).distinct
/* ある投稿に紐づくコメントについて、user_idが一意のレコードを取得する */

こんな感じで指定ができるようです!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?