Help us understand the problem. What is going on with this article?

ActiveRecordのdistinctメソッドを使って、一意なデータのみを取得する方法

一意なデータを取ってくる方法を探していた時、ActiveRecordのdistinctメソッドを発見したため、実際どのようなSQLを発行しているのかし調べてみました。
下記のようなテーブルがあったとします。Userテーブルが親でTaskテーブルは子の状況です。

Userテーブル

id name color
1 Bob blue
2 Tom red
3 Emi black
4 Rick red
5 Goto red
6 Alice black

Taskテーブル

id user_id task
1 1 掃除
2 4 宿題
3 1 風呂掃除
4 6 買い物
5 3 昼寝
6 4 野球
User.all.distinct

Userテーブルの全てのデータを取得し、そこにdistinctメソッドを実行しました。以下のようなSQLになります。

SELECT  DISTINCT `users`.* FROM `users`

テーブルから取得した列に対して重複を省いています。今回の場合、全ての列を取得しているため、重複が発生することはありません。(そもそもidは一意だから。)

User.select("color").distinct

取得する列をcolorで絞ってみましょう。

SELECT  DISTINCT `users`.`color` FROM `users`

すると、取得できるデータはblue、red、blackの3つのみになるはずです。distinctメソッドを使用することで6つ全てのデータを取得するのではなく、値が重複している分のredとblackのデータは除かれます。これはUsersテーブルにあるcolorの列に対してDISTINCTを実行しているからです。

では結合(inner join)させた場合はどうなるでしょうか?タスクを作成しているユーザーのみを取得したい時、下記のようなものができます。

User.joins(:tasks).distinct
SELECT  DISTINCT `users`.* FROM `users` INNER JOIN `tasks` ON `tasks`.`users._id` = `users`.`id`

取得するデータは4つになるはずです。取得したデータの中でUsersテーブルのレコードが同じものがあった場合、その重複分は排除されます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした