回答編集履歴

3

加筆修正

2017/01/06 10:07

投稿

退会済みユーザー
test CHANGED
@@ -46,11 +46,21 @@
46
46
 
47
47
  A.Ichi さんの回答との違いは、
48
48
 
49
- ほうが先にgroup byを使っ集約した結果に対して、
49
+ A.Ichi さんは全行連結してからgroup byいるのに対して、
50
50
 
51
- placeテーブルを結合させいることです。
51
+ 私のほうが先にgroup by使って集約した果を作っ
52
52
 
53
+ それにplaceテーブルを結合させていることです。
54
+
55
+ group byする対象のテーブルのレコード数が膨大になっていると
56
+
57
+ 全行連結してからのgroup byでは必要とするメモリが多くなりがちなので、
58
+
59
+ 先にgroup byしてしまう方が良いと考えました。
60
+
61
+
62
+
53
- coalesce()は結果がNULLだったときに代理で値を与えたりするのに便利です。
63
+ `coalesce()`は結果がNULLだったときに代理で値を与えたりするのに便利です。
54
64
 
55
65
 
56
66
 

2

加筆修正

2017/01/06 10:06

投稿

退会済みユーザー
test CHANGED
@@ -44,6 +44,22 @@
44
44
 
45
45
  って形でしょうか。
46
46
 
47
+ A.Ichi さんの回答との違いは、
48
+
49
+ 私のほうが先にgroup byを使って集約した結果に対して、
50
+
51
+ placeテーブルを結合させていることです。
52
+
53
+ coalesce()は結果がNULLだったときに代理で値を与えたりするのに便利です。
54
+
55
+
56
+
57
+ 参考:9.17. 条件式
58
+
59
+ [http://www.postgresql.jp/document/9.6/html/functions-conditional.html](http://www.postgresql.jp/document/9.6/html/functions-conditional.html)
60
+
61
+
62
+
47
63
 
48
64
 
49
65
  余談ですが、結合先のテーブルがない場合は、`generate_series(start, stop)` が有効です。

1

加筆修正

2017/01/06 10:03

投稿

退会済みユーザー
test CHANGED
@@ -1,14 +1,52 @@
1
+ placeってテーブルにidが全部入っている、という前提で。
2
+
3
+ ```sql
4
+
5
+ SELECT
6
+
1
- `values(1,2,3,4,5,6,7,8,9) as place(place_id)` みたいなテーブルに対して left join l_test すれば、place_idを1から9まで確保できると思います。
7
+ p.id, coalesce(l.a1, 0) as a1, coalesce(l.a2, 0) as a2, coalesce(l.a3, 0) as a3, coalesce(l.a4, 0) as a4, coalesce(l.a5, 0) as a5
8
+
9
+ FROM (
10
+
11
+ SELECT place_id,
12
+
13
+ sum(case when (l.type = '01') then 1 else 0 end ) as a1,
14
+
15
+ sum(case when (l.type != '01') then 1 else 0 end ) as a2,
16
+
17
+ sum(case when (l.type = '02') then 1 else 0 end ) as a3,
18
+
19
+ sum(case when (l.type = '03') then 1 else 0 end ) as a4,
20
+
21
+ sum(case when (l.out in ('02','03') ) then 1 else 0 end ) as a5
22
+
23
+ FROM l_test
24
+
25
+ WHERE
26
+
27
+ l.day >= '20150441' and l.day <= '20160331'
28
+
29
+ GROUP BY l.place_id
30
+
31
+ ) as l
32
+
33
+ RIGHT JOIN
34
+
35
+ place as p on l.place_id = p.id
36
+
37
+ ORDER BY
38
+
39
+ p.id;
40
+
41
+ ```
2
42
 
3
43
 
4
44
 
5
- place_idがもと広範囲になるよであれば、
45
+ て形でしょか。
6
46
 
7
- `generate_series(start, stop)`を活用して、
8
47
 
9
- `select * from generate_series(1, 47)` なんて書くと1から47まで生成してくれるので、
10
48
 
11
- 結果に対して left joinればよいかと
49
+ 余談ですが、結合先テーブルがない場合は、`generate_series(start, stop)` が有効です。
12
50
 
13
51
 
14
52