回答編集履歴

3

distinct を書き忘れる痛恨のミス

2021/04/13 10:08

投稿

shinoharat
shinoharat

スコア1685

test CHANGED
@@ -9,6 +9,8 @@
9
9
  .where(country: { area: 3 })
10
10
 
11
11
  .where(user: { id: 20 })
12
+
13
+ .distinct
12
14
 
13
15
  .count(:language)
14
16
 
@@ -22,20 +24,20 @@
22
24
 
23
25
  ```sql
24
26
 
25
- (0.2ms)
27
+ (0.4ms)
26
28
 
27
- SELECT COUNT("questions"."language")
29
+ SELECT COUNT(DISTINCT "questions"."language")
28
30
 
29
- FROM "questions"
31
+ FROM "questions"
30
32
 
31
- INNER JOIN "units" ON "units"."id" = "questions"."unit_id"
33
+ INNER JOIN "units" ON "units"."id" = "questions"."unit_id"
32
34
 
33
- INNER JOIN "subjects" ON "subjects"."id" = "units"."subject_id"
35
+ INNER JOIN "subjects" ON "subjects"."id" = "units"."subject_id"
34
36
 
35
- INNER JOIN "users" user ON user."id" = "subjects"."user_id"
37
+ INNER JOIN "users" user ON user."id" = "subjects"."user_id"
36
38
 
37
- INNER JOIN "countries" country ON country."id" = user."country_id"
39
+ INNER JOIN "countries" country ON country."id" = user."country_id"
38
40
 
39
- WHERE "country"."area" = ? AND "user"."id" = ? [["area", 3], ["id", 2]]
41
+ WHERE "country"."area" = ? AND "user"."id" = ? [["area", 3], ["id", 20]]
40
42
 
41
43
  ```

2

カウントを取得するSQLに修正

2021/04/13 10:08

投稿

shinoharat
shinoharat

スコア1685

test CHANGED
@@ -1,61 +1,41 @@
1
- > - countryのareaカラムが3
2
-
3
- > - userのidが20、
1
+ これでどうでしょうか?
4
-
5
-
6
-
7
- の条件に合う Question であれば、以下のコードで取得できます。
8
2
 
9
3
 
10
4
 
11
5
  ```rb
12
6
 
13
- Question.joins(unit: { subject: { user: :country } })
7
+ language_count = Question.joins(unit: { subject: { user: :country } })
14
8
 
15
- .where(country: { area: 3 })
9
+ .where(country: { area: 3 })
16
10
 
17
- .where(user: { id: 20 })
11
+ .where(user: { id: 20 })
12
+
13
+ .count(:language)
18
14
 
19
15
  ```
20
16
 
21
17
 
22
18
 
23
- --
19
+ 生成されるSQLは以下の通りです。
24
20
 
25
21
 
26
22
 
27
- > - questionのlanguageカラムで重複しているデータを省く
23
+ ```sql
28
24
 
25
+ (0.2ms)
29
26
 
27
+ SELECT COUNT("questions"."language")
30
28
 
31
- 上記の記述について、質問者さんがどのような結果を求めておられるのか良く分かりませんでした。
29
+ FROM "questions"
32
30
 
31
+ INNER JOIN "units" ON "units"."id" = "questions"."unit_id"
33
32
 
33
+ INNER JOIN "subjects" ON "subjects"."id" = "units"."subject_id"
34
34
 
35
- もし、単純に重複なしの language のリストを取得したいなら、
35
+ INNER JOIN "users" user ON user."id" = "subjects"."user_id"
36
36
 
37
- `.distinct(:language).pluck(:language)` を加えればよいです。
37
+ INNER JOIN "countries" country ON country."id" = user."country_id"
38
38
 
39
-
40
-
41
- ```rb
42
-
43
- languages = Question.joins(unit: { subject: { user: :country } })
44
-
45
- .where(country: { area: 3 })
46
-
47
- .where(user: { id: 20 })
48
-
49
- .distinct(:language)
50
-
51
- .pluck(:language)
52
-
53
-
54
-
55
- # (languages ["foo", "bar"] のような文字列の配列)
39
+ WHERE "country"."area" = ? AND "user"."id" = ? [["area", 3], ["id", 2]]
56
40
 
57
41
  ```
58
-
59
-
60
-
61
- しかし、「language が重複していたら、そのうちの1レコードを取得」という結果を求められているのであれば、重複時にどういう条件に基づいてレコードを取得するのかを決める必要があります。

1

誤字修正

2021/04/13 09:55

投稿

shinoharat
shinoharat

スコア1685

test CHANGED
@@ -32,7 +32,9 @@
32
32
 
33
33
 
34
34
 
35
+ もし、単純に重複なしの language のリストを取得したいなら、
36
+
35
- もし、単純に重複なしの language のリストを取得したいなら、 `.distinct(:language).pluck(:language)` を加えればよいです。
37
+ `.distinct(:language).pluck(:language)` を加えればよいです。
36
38
 
37
39
 
38
40