質問編集履歴

4

コード修正

2016/06/29 09:15

投稿

poyopi
poyopi

スコア113

test CHANGED
File without changes
test CHANGED
@@ -180,7 +180,7 @@
180
180
 
181
181
  ```XML
182
182
 
183
- <select id="search" resultType="sso.repository.SSODTO">
183
+ <select id="search" resultType="package.DTOclass">
184
184
 
185
185
  SELECT
186
186
 

3

参考先追加

2016/06/29 09:15

投稿

poyopi
poyopi

スコア113

test CHANGED
File without changes
test CHANGED
@@ -220,7 +220,7 @@
220
220
 
221
221
  ```
222
222
 
223
- 最初はまったのは、テーブル名を普通にバインド(```#{rotate}```みたいに)しようとしたらException(```org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"```)を出されてしまったことです。テーブル名はバインドできなさそうです。MyBatisじゃなくてiBatisですが参考:[iBatis奮闘記-0013 ($を使用した動的パラメータ) - いろいろ備忘録日記](http://devlights.hatenablog.com/entry/20060908/p1)
223
+ 最初はまったのは、テーブル名を普通にバインド(```#{rotate}```みたいに)しようとしたらException(```org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"```)を出されてしまったことです。テーブル名はバインドできなさそうです。参考:[mybatis/old-google-code-issues - github](https://github.com/mybatis/old-google-code-issues/blob/master/wiki/FaqJapanese.wiki)、[iBatis奮闘記-0013 ($を使用した動的パラメータ) - いろいろ備忘録日記](http://devlights.hatenablog.com/entry/20060908/p1)
224
224
 
225
225
 
226
226
 

2

解決策備忘録として追記

2016/06/28 09:45

投稿

poyopi
poyopi

スコア113

test CHANGED
File without changes
test CHANGED
@@ -1,3 +1,9 @@
1
+ **最終的な解決?を最下部に追記しています。ご参考まで**
2
+
3
+ ご回答いただいた[iwamoto_takaaki](https://teratail.com/users/iwamoto_takaaki)さん、[masuda_yuya](https://teratail.com/users/masuda_yuya)さん、ありがとうございます。
4
+
5
+
6
+
1
7
  DB接続をするWEBアプリケーションを作っているのですが、掲題について悩んでいるので質問させてください。
2
8
 
3
9
 
@@ -12,7 +18,7 @@
12
18
 
13
19
  ```SQL
14
20
 
15
- SSELECT * FROM
21
+ SELECT * FROM
16
22
 
17
23
  (SELECT * FROM table)AS table UNION ALL SELECT * FROM
18
24
 
@@ -91,3 +97,131 @@
91
97
  ```
92
98
 
93
99
  ↑6/27の0時から7時まで……の条件のつもりだが、普通に現在(17時とか)から最新順で100件になってしまう。条件を別の項目に変え(```where hoge='piyo'```みたいな)ても効いておらず、普通に全データの最新100件が返される。
100
+
101
+
102
+
103
+ ---
104
+
105
+ 06/28
106
+
107
+ [masuda_yuya](https://teratail.com/users/masuda_yuya)さんのご指摘にてSQLの文法の誤りを認識。改修して、ベタSQLとしてはこういう感じになりました:
108
+
109
+ ```SQL
110
+
111
+ select*from (
112
+
113
+ select*from table
114
+
115
+ union all select*from table_yyyyMMdd
116
+
117
+ union all select*from table_yyyyMMdd
118
+
119
+ union all select*from table_yyyyMMdd
120
+
121
+ ) tables
122
+
123
+ where tables.access_time <= to_timestamp('2016/06/27 06:00','YYYY/MM/DD HH24:MI')
124
+
125
+ and tables.access_time >= to_timestamp('2016/06/27 01:00','YYYY/MM/DD HH24:MI')
126
+
127
+ order by tables.access_date desc limit 100 offset 1
128
+
129
+ ```
130
+
131
+ WHERE句の条件は適当でよく、正常に結果が抽出できるかどうかの確認となります。問題なさそうだったので、動的SQLにするためにjavaをいじります。
132
+
133
+ - yyyyMMdd部分の生成
134
+
135
+ メインのテーブルが「table」で、本日分のデータのみが載っている。日次でローテートされ、ローテートされるとテーブル名の末尾に「_yyyyMMdd」が付与される。ここでは過去10日分のみ保持。
136
+
137
+ とりあえず、SQL組み立てでバインドのため利用している変数を宣言しているクラス内に、過去10日間のテーブル名を返すgetメソッドを作りました。
138
+
139
+ ```java
140
+
141
+ public List<String> getRotateTables(){
142
+
143
+ SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMdd");
144
+
145
+ Calendar t =Calendar.getInstance();
146
+
147
+ List<String> list=new ArrayList<>();
148
+
149
+ String[] tmp = new String[10];
150
+
151
+ for(int i=0;i<=9;i++){
152
+
153
+ t.add(Calendar.DAY_OF_YEAR, -1);
154
+
155
+ tmp[i]="table_"+dateFormat.format(t.getTime()).toString();
156
+
157
+ }
158
+
159
+ list.addAll(Arrays.asList(tmp));
160
+
161
+ return list;
162
+
163
+ }
164
+
165
+ ```
166
+
167
+ きたないっぽいですが動作すること優先で進みます。
168
+
169
+
170
+
171
+ - Mapperインタフェースに上記のパラメータ追加
172
+
173
+ - Mapper使っているDAOに上記パラメータ追加
174
+
175
+ - 検索やページングのActionクラスにも追加
176
+
177
+
178
+
179
+ 最終的にSQLを組み立てているXMLを書きます。大体こういう感じです:
180
+
181
+ ```XML
182
+
183
+ <select id="search" resultType="sso.repository.SSODTO">
184
+
185
+ SELECT
186
+
187
+ * FROM
188
+
189
+ (
190
+
191
+ SELECT * FROM table
192
+
193
+ <foreach item="rotate" collection="rotateList" separator=" ">
194
+
195
+ UNION ALL SELECT * FROM ${rotate}
196
+
197
+ </foreach>
198
+
199
+ ) tables
200
+
201
+ <where>
202
+
203
+ <if test="from!=null and from!=''">
204
+
205
+ AND tables.access_time &gt;= to_timestamp(#{from},'YYYY/MM/DD HH24:MI')
206
+
207
+ </if>
208
+
209
+ <if test="to!=null and to!=''">
210
+
211
+ AND tables.access_time &lt;= to_timestamp(#{to},'YYYY/MM/DD HH24:MI')
212
+
213
+ </if>
214
+
215
+ </where>
216
+
217
+ ORDER BY tables.access_time DESC LIMIT 100 OFFSET #{counter}
218
+
219
+ </select>
220
+
221
+ ```
222
+
223
+ 最初はまったのは、テーブル名を普通にバインド(```#{rotate}```みたいに)しようとしたらException(```org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"```)を出されてしまったことです。テーブル名はバインドできなさそうです。MyBatisじゃなくてiBatisですが参考:[iBatis奮闘記-0013 ($を使用した動的パラメータ) - いろいろ備忘録日記](http://devlights.hatenablog.com/entry/20060908/p1)
224
+
225
+
226
+
227
+ 検索のために複数テーブルを含めて抽出という目的が達成されたのでクローズします。

1

検証して浮上した別問題について追記

2016/06/28 09:02

投稿

poyopi
poyopi

スコア113

test CHANGED
File without changes
test CHANGED
@@ -38,13 +38,13 @@
38
38
 
39
39
  <if test="startTime!=null and startTime!=''">
40
40
 
41
- AND time &gt;= to_timestamp(#{start}, 'YYYY/MM/DD HH24:MI')
41
+ AND access_time &gt;= to_timestamp(#{start}, 'YYYY/MM/DD HH24:MI')
42
42
 
43
43
  </if>
44
44
 
45
45
  <if test="endTime!=null and endTime=''">
46
46
 
47
- AND time &lt;= to_timestamp(#{end}, 'YYYY/MM/DD HH24:MI')
47
+ AND access_time &lt;= to_timestamp(#{end}, 'YYYY/MM/DD HH24:MI')
48
48
 
49
49
  </if>
50
50
 
@@ -61,3 +61,33 @@
61
61
 
62
62
 
63
63
  postgresqlですが、Oracleだったらこう書けるよ、とかでもよいので、何かよりよくするためのご助言を頂ければと思います。
64
+
65
+
66
+
67
+ ---
68
+
69
+ ひとまずプログラムの中に組み込む前にベタSQLで結果を試してみたところ、当初質問を立てた意図とは変わりますが、うまくいかない部分があったので解決するまでこの質問をあけておきます(解決後質問文に顛末を追記します)。
70
+
71
+ なお、明示的に回答を求めず自己解決の心づもりでおりますが、下記に目を通してお気づきの点ございましたらご助言頂けますと幸甚です。
72
+
73
+
74
+
75
+ **問題:where句が効いてない**
76
+
77
+ ```SQL
78
+
79
+ select*from table
80
+
81
+ union all select*from table_20160626
82
+
83
+ union all select*from table_20160625
84
+
85
+ union all select*from table_20160624
86
+
87
+ where access_time >= to_timestamp('2016/06/27 00:00','YYYY/MM/DD HH24:MI') and access_time <= to_timestamp('2016/06/27 07:00','YYYY/MM/DD HH24:MI')
88
+
89
+ order by access_time desc limit 100 offset 1
90
+
91
+ ```
92
+
93
+ ↑6/27の0時から7時まで……の条件のつもりだが、普通に現在(17時とか)から最新順で100件になってしまう。条件を別の項目に変え(```where hoge='piyo'```みたいな)ても効いておらず、普通に全データの最新100件が返される。