teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

加筆修正

2017/01/06 10:07

投稿

退会済みユーザー
answer CHANGED
@@ -22,10 +22,15 @@
22
22
 
23
23
  って形でしょうか。
24
24
  A.Ichi さんの回答との違いは、
25
+ A.Ichi さんのは全行連結してからgroup byしているのに対して、
25
- 私のほうが先にgroup byを使って集約した結果に対して、
26
+ 私のほうが先にgroup byを使って集約した結果を作って、
26
- placeテーブルを結合させていることです。
27
+ それにplaceテーブルを結合させていることです。
28
+ group byする対象のテーブルのレコード数が膨大になっていると
27
- coalesce()は果がNULLだったときに代理値を与えたりするのに便利す。
29
+ 全行連してからのgroup byは必要とするメモリが多くなりがちなので
30
+ 先にgroup byしてしまう方が良いと考えました。
28
31
 
32
+ `coalesce()`は結果がNULLだったときに代理で値を与えたりするのに便利です。
33
+
29
34
  参考:9.17. 条件式
30
35
  [http://www.postgresql.jp/document/9.6/html/functions-conditional.html](http://www.postgresql.jp/document/9.6/html/functions-conditional.html)
31
36
 

2

加筆修正

2017/01/06 10:06

投稿

退会済みユーザー
answer CHANGED
@@ -21,7 +21,15 @@
21
21
  ```
22
22
 
23
23
  って形でしょうか。
24
+ A.Ichi さんの回答との違いは、
25
+ 私のほうが先にgroup byを使って集約した結果に対して、
26
+ placeテーブルを結合させていることです。
27
+ coalesce()は結果がNULLだったときに代理で値を与えたりするのに便利です。
24
28
 
29
+ 参考:9.17. 条件式
30
+ [http://www.postgresql.jp/document/9.6/html/functions-conditional.html](http://www.postgresql.jp/document/9.6/html/functions-conditional.html)
31
+
32
+
25
33
  余談ですが、結合先のテーブルがない場合は、`generate_series(start, stop)` が有効です。
26
34
 
27
35
  参考:generate_series()

1

加筆修正

2017/01/06 10:03

投稿

退会済みユーザー
answer CHANGED
@@ -1,9 +1,28 @@
1
+ placeってテーブルにidが全部入っている、という前提で。
2
+ ```sql
3
+ SELECT
1
- `values(1,2,3,4,5,6,7,8,9) as place(place_id)` みたいなテーブルに対して left join l_test すれば、place_idを1から9まで確保できると思います。
4
+ 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
5
+ FROM (
6
+ SELECT place_id,
7
+ sum(case when (l.type = '01') then 1 else 0 end ) as a1,
8
+ sum(case when (l.type != '01') then 1 else 0 end ) as a2,
9
+ sum(case when (l.type = '02') then 1 else 0 end ) as a3,
10
+ sum(case when (l.type = '03') then 1 else 0 end ) as a4,
11
+ sum(case when (l.out in ('02','03') ) then 1 else 0 end ) as a5
12
+ FROM l_test
13
+ WHERE
14
+ l.day >= '20150441' and l.day <= '20160331'
15
+ GROUP BY l.place_id
16
+ ) as l
17
+ RIGHT JOIN
18
+ place as p on l.place_id = p.id
19
+ ORDER BY
20
+ p.id;
21
+ ```
2
22
 
3
- place_idがもっと広範囲になるようであれば、
4
- `generate_series(start, stop)`を活用して、
5
- `select * from generate_series(1, 47)` なんて書くと1から47まで生成してくれるので、
6
- この結果に対し left join すればよい
23
+ 形でしょうか。
7
24
 
25
+ 余談ですが、結合先のテーブルがない場合は、`generate_series(start, stop)` が有効です。
26
+
8
27
  参考:generate_series()
9
28
  [http://www.postgresql.jp/document/9.6/html/functions-srf.html](http://www.postgresql.jp/document/9.6/html/functions-srf.html)