質問編集履歴
2
関数記載項目の修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -106,11 +106,9 @@
|
|
106
106
|
|
107
107
|
RETURNS TABLE(
|
108
108
|
|
109
|
-
_id integer,
|
110
|
-
|
111
109
|
_timestamp timestamp(3) without time zone,
|
112
110
|
|
113
|
-
_
|
111
|
+
_data text
|
114
112
|
|
115
113
|
) AS $$
|
116
114
|
|
1
実現したいことを具体的に追記しました
test
CHANGED
File without changes
|
test
CHANGED
@@ -40,8 +40,6 @@
|
|
40
40
|
|
41
41
|
|
42
42
|
|
43
|
-
例えば今日の日付を2020/11/4とします。
|
44
|
-
|
45
43
|
|
46
44
|
|
47
45
|
0. 直近一年以内のデータを参照するときには、PostgreSQL内のテーブルからデータを参照したいです。
|
@@ -56,15 +54,17 @@
|
|
56
54
|
|
57
55
|
|
58
56
|
|
59
|
-
ただし、クエリ文のFrom句は、直近一年分のデータを参照するときと一年以上前を参照するときで変更できません
|
57
|
+
ただし、**問い合わせるクエリ文(青四角部)のFrom句は、直近一年分のデータを参照するときと一年以上前を参照するときで変更できません**
|
60
58
|
|
61
59
|
これは問い合わせ側の制約になります。
|
62
60
|
|
63
|
-
そのため、**Where句のタイムスタンプの日付を読み取り一年以上前のデータを参照しようとした際には、内部的にFrom句のテーブルを外部テーブルに変更する必要があります**。
|
64
61
|
|
65
62
|
|
66
63
|
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
-
実行
|
67
|
+
例えば実行日時を2020-11-04 00:00:00とした際に以下のクエリを受け取るとします。
|
68
68
|
|
69
69
|
```
|
70
70
|
|
@@ -72,21 +72,113 @@
|
|
72
72
|
|
73
73
|
From TABLE
|
74
74
|
|
75
|
-
Where ‘2019-11-04’ >= _timestamp
|
75
|
+
Where ‘2019-11-04 00:03:00’ >= _timestamp and _timestamp >= '2019-11-04 00:00:00'
|
76
76
|
|
77
77
|
```
|
78
78
|
|
79
|
-
|
79
|
+
この場合、一年以上前のデータになるため、From句を変更して外部テーブルにアクセスする必要があります。
|
80
|
+
|
81
|
+
また、csvは毎分ごとに作成されるものになるため、上記のようなWhere句の場合以下の3つのcsvにアクセスする必要があります。
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
* アクセスする必要のあるテーブル名
|
86
|
+
|
87
|
+
TABLE_2020110403
|
88
|
+
|
89
|
+
TABLE_2020110402
|
90
|
+
|
91
|
+
TABLE_2020110401
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
現在想定している手法は、拡張機能でアクセスする必要のあるテーブル名のARRAYを作成し、以下の関数によって各テーブルの結果を結合することです。
|
98
|
+
|
99
|
+
```ここに言語を入力
|
100
|
+
|
101
|
+
DROP FUNCTION IF EXISTS csv(csv_names text[]);
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
CREATE OR REPLACE FUNCTION csv(csv_names text[])
|
106
|
+
|
107
|
+
RETURNS TABLE(
|
108
|
+
|
109
|
+
_id integer,
|
110
|
+
|
111
|
+
_timestamp timestamp(3) without time zone,
|
112
|
+
|
113
|
+
_source text
|
114
|
+
|
115
|
+
) AS $$
|
116
|
+
|
117
|
+
DECLARE
|
118
|
+
|
119
|
+
csv_name text;
|
120
|
+
|
121
|
+
Begin
|
122
|
+
|
123
|
+
FOREACH csv_name IN ARRAY csv_names LOOP
|
124
|
+
|
125
|
+
RETURN QUERY EXECUTE format('Select * FROM %I', csv_name);
|
126
|
+
|
127
|
+
END LOOP;
|
128
|
+
|
129
|
+
END;
|
130
|
+
|
131
|
+
$$ LANGUAGE plpgsql;
|
132
|
+
|
133
|
+
```
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
### 行き詰っているところ
|
138
|
+
|
139
|
+
以下の2の手順における、1の手順で受けたクエリのWhere句に応じて、リストを作成する工程で行き詰っています。
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
1. クエリを受け取る
|
80
144
|
|
81
145
|
```
|
82
146
|
|
83
147
|
Select *
|
84
148
|
|
85
|
-
From TABLE
|
149
|
+
From TABLE
|
86
150
|
|
87
|
-
Where ‘2019-11-04’ >= _timestamp
|
151
|
+
Where ‘2019-11-04 00:03:00’ >= _timestamp and _timestamp >= '2019-11-04 00:00:00'
|
88
152
|
|
89
153
|
```
|
154
|
+
|
155
|
+
2. 一年以上前のデータなので、**上記のクエリは実行せずに**、以下のリストを作成する
|
156
|
+
|
157
|
+
```ここに言語を入力
|
158
|
+
|
159
|
+
[TABLE_2020110403, TABLE_2020110402, TABLE_2020110401]
|
160
|
+
|
161
|
+
```
|
162
|
+
|
163
|
+
3. 2のリストを受け取って、関数(csv)に引数として与えて、処理を実行する
|
164
|
+
|
165
|
+
```ここに言語を入力
|
166
|
+
|
167
|
+
Select *
|
168
|
+
|
169
|
+
FROM csv(ARRAY[‘TABLE_2020110403’, ‘TABLE_2020110402’, ‘TABLE_2020110401’]
|
170
|
+
|
171
|
+
Where ‘2019-11-04 00:03:00’ >= _timestamp and _timestamp >= '2019-11-04 00:00:00'
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
```
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
拡張機能であればこの処理が実現できるのかもしれませんが、具体的な手法が思いつきません。
|
180
|
+
|
181
|
+
|
90
182
|
|
91
183
|
|
92
184
|
|
@@ -96,6 +188,6 @@
|
|
96
188
|
|
97
189
|
### 設計上の制約
|
98
190
|
|
99
|
-
*
|
191
|
+
* 受け取るクエリのFrom句は変更できない
|
100
192
|
|
101
|
-
* PostgreSQ
|
193
|
+
* PostgreSQLのVerを変更することはできない
|