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

回答編集履歴

7

推敲

2020/11/17 14:52

投稿

sazi
sazi

スコア25430

answer CHANGED
@@ -39,4 +39,6 @@
39
39
 
40
40
  > DB初心者です
41
41
 
42
+ 初心者レベルならSQLのみでは解決できません。
43
+ テーブルを日時順に読み込んで、start、endを作成するような処理になるはずです。
42
- 初心者にこれを任せるプロジェクトというのは、前途多難ですね。
44
+ 指針もなくこれを丸投げするプロジェクトだったりすると、前途多難ですね。

6

推敲

2020/11/17 14:52

投稿

sazi
sazi

スコア25430

answer CHANGED
@@ -39,4 +39,4 @@
39
39
 
40
40
  > DB初心者です
41
41
 
42
- 前途多難ですね。
42
+ 初心者にこれを任せるプロジェクトというのは、前途多難ですね。

5

修正

2020/11/17 14:46

投稿

sazi
sazi

スコア25430

answer CHANGED
@@ -3,6 +3,7 @@
3
3
  連続したerror_dateからみて、machineとerror_codeが変わるタイミングがブレークポイントです。
4
4
  そのブレークポイントを個々のデータにグループの情報として割り当て、全体を集計します。
5
5
  区切りの情報を生成するには[lag()やlead()のwindow関数](https://lets.postgresql.jp/documents/technical/window_functions/1)を用います。
6
+ ※文字列の結合だと組合せで同じになるかもしれないのでarray[]に変更
6
7
  ```SQL
7
8
  with step1 as (
8
9
  select *

4

修正

2020/11/17 11:37

投稿

sazi
sazi

スコア25430

answer CHANGED
@@ -6,10 +6,11 @@
6
6
  ```SQL
7
7
  with step1 as (
8
8
  select *
9
- , lag(machine || error_code, 1, '') over(order by error_date) lag_key
9
+ , lag(array[machine, error_code] ::text[], 1, array['',''])
10
+ over(order by error_date) lag_key
10
11
  from tr_machine_error
11
12
  ), step2 as (
12
- select case when machine || error_code != lag_key then error_date end error_start
13
+ select case when array[machine, error_code] ::text[] != lag_key then error_date end error_start
13
14
  from step1
14
15
  ) , step3 as (
15
16
  select error_start

3

追記

2020/11/17 11:36

投稿

sazi
sazi

スコア25430

answer CHANGED
@@ -33,4 +33,8 @@
33
33
  **step4:**lead()を用いて、error_startでグルーピングする範囲を作成します。
34
34
  **最終:**step4の情報と結合し、集計によってerror_endを求めます。
35
35
 
36
- ぱっと思いついて組み立てただけなので、観点を変えると簡潔な記述があるかもしれません。
36
+ ぱっと思いついて組み立てただけなので、観点を変えると簡潔な記述があるかもしれません。
37
+
38
+ > DB初心者です
39
+
40
+ 前途多難ですね。

2

名称を合わせた

2020/11/17 11:28

投稿

sazi
sazi

スコア25430

answer CHANGED
@@ -7,7 +7,7 @@
7
7
  with step1 as (
8
8
  select *
9
9
  , lag(machine || error_code, 1, '') over(order by error_date) lag_key
10
- from log
10
+ from tr_machine_error
11
11
  ), step2 as (
12
12
  select case when machine || error_code != lag_key then error_date end error_start
13
13
  from step1
@@ -20,9 +20,9 @@
20
20
  from step3
21
21
  )
22
22
  select machine, error_code, error_start, max(error_date) as error_end
23
- from log left join step4
23
+ from tr_machine_error left join step4
24
- on log.error_date >= step4.error_start
24
+ on tr_machine_error.error_date >= step4.error_start
25
- and (log.error_date < lead_error_start or lead_error_start is null)
25
+ and (tr_machine_error.error_date < lead_error_start or lead_error_start is null)
26
26
  group by machine, error_code, error_start
27
27
  order by error_start
28
28
  ```

1

推敲

2020/11/17 11:22

投稿

sazi
sazi

スコア25430

answer CHANGED
@@ -30,7 +30,7 @@
30
30
  **step1:**lag()を用い直前のmachine, error_codeを取得します。
31
31
  **step2:**step1の情報を元にブレークしている場所のみerror_startを設定します。
32
32
  **step3:**step4で使用するlead()用にerror_startが設定されている情報のみにします。
33
- **step4:**error_startでグルーピングする範囲を作成します。
33
+ **step4:**lead()を用いて、error_startでグルーピングする範囲を作成します。
34
34
  **最終:**step4の情報と結合し、集計によってerror_endを求めます。
35
35
 
36
36
  ぱっと思いついて組み立てただけなので、観点を変えると簡潔な記述があるかもしれません。