質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.01%

ArrayListのデータ挿入について

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,265

freeair.

score 11

List<aaaEntity> list = new ArrayList<aaaEntity>();
while (result.next()) {
                aaaEntity entity = new aaaEntity();

                entity.setHoge(result.getString("hoge"));
                entity.setVar(result.geString("var"));
                entity.setDate(result.getString("date"));
                entity.setCost(result.getString("cost"));
                list.add(entity);
            }


データ(hoge,var,date,cost)の入ったリストを作る上記のようなものがあるのですが、
実際のソースコードの仕組み上whileを二つに分けて作ったので、最終的に纏めあげるようなことをして、上記と同じリストにしたいのですが
下記のように、list.addを使用するとdateとcostだけの独立した要素が挿入されてしまうのでどうすればよいか分かりません。
ご教示のほどお願いします。よろしくお願いします。

String sql = createSql();
PreparedStatement stmt = null;
ResultSet result = null;

String sql2 = createSql2();
PreparedStatement stmt2 = null;
ResultSet result2 = null;
try{
        stmt = getConn().prepareStatement(sql);
        stmt.setString(1, aiu);
        result = stmt.executeQuery();


        stmt2 = getConn().prepareStatement(sql2);
        stmt2.setString(1, aiu);  
        result2 = stmt.executeQuery();


        while (result.next()) {
                aaaEntity entity = new aaaEntity();

                entity.setHoge(result.getString("hoge"));
                entity.setVar(result.geString("var"));
                list.add(entity);
        }
        int row = 0;
        while (result2.next()) {
                aaaEntity entity = new aaaEntity();

                entity.setDate(result2.getString("date"));
                entity.setCost(result2.getString("cost"));
                list.add(row, entity);
                row++;
        }
}

private String createSql() {
        StringBuilder sb = new StringBuilder();

        sb.append(" SELECT");
        sb.append("   hoge");
        sb.append("  ,var");
        sb.append("  ,date");
        sb.append(" FROM");
        sb.append("   testtable");
        sb.append(" WHERE date = ?");
        return sb.toString();
}
private String createSql2() {
        StringBuilder sb = new StringBuilder();

        sb.append(" SELECT");
        sb.append("   date");
        sb.append("  ,cost");
        sb.append(" FROM");
        sb.append("   testtable2");
        sb.append(" WHERE date = ?");
        return sb.toString();
}

補足--
createSqlとcreateSql2を結合したら多分こんな感じです。

private String createSql() {
        StringBuilder sb = new StringBuilder();

        sb.append(" SELECT");
        sb.append("   ttbl1.hoge");
        sb.append("  ,ttbl1.var");
        sb.append("  ,ttbl2.date");
        sb.append("  ,ttbl2.cost");
        sb.append(" FROM");

        sb.append(" (SELECT");
        sb.append("   hoge");
        sb.append("  ,var");
        sb.append("  ,date");
        sb.append(" FROM");
        sb.append("   testtable");
        sb.append(" WHERE date = ?");
        sb.append(" ) ttbl1");

        sb.append(" INNER JOIN");
        sb.append(" (SELECT");
        sb.append("   date");
        sb.append("  ,cost");
        sb.append(" FROM");
        sb.append("   testtable2");
        sb.append(" WHERE date = ?");
        sb.append(" ) ttbl2");

        sb.append(" (ttbl1.date = ttbl2.date) ");

        return sb.toString();
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • KiyoshiMotoki

    2016/11/09 12:16

    変数 result は java.sql.ResultSet インターフェースでしょうか? であれば、2回に分けて実行しているSQL文を結合し、1回のクエリ実行でデータを取得できるようにするのがもっとも無難な修正方法だと考えます。「その方法が分からない」ということであれば、実行しているSQL文を質問欄に追記してください。

    キャンセル

  • freeair.

    2016/11/09 13:29

    編集しました。sql文二つをINNNER JOINで結合した新しいsql文を追加することはできますけど、必ずしも両方のテーブルにデータがあるわけではないのでそのときwhile内の処理は動きません・・・。処理で二つのsql文を結合する方法はわからないです。

    キャンセル

  • KiyoshiMotoki

    2016/11/09 14:34

    情報の追記、ありがとうございます。「sql文二つをINNNER JOINで結合した新しいsql文を追加することはでき」る、とのことですが、その際の結合条件はどのようになりますか?また、「必ずしも両方のテーブルにデータがあるわけではない」とは具体的にはどのような状況ですか?「testtable にあって testtable2 にないデータがあり得る」のか、「testtable2 にあって testtable にないデータがあり得る」のか、それとも「その両方のケースがあり得る」のか。

    キャンセル

  • freeair.

    2016/11/09 14:52

    有難うございます、補足しました。見づらくてすみません。「testtable2 にあってtesttable にないデータが有り得る」←これだと思います。

    キャンセル

回答 4

checkベストアンサー

+2

回答欄やコメント欄に追記いただいた情報を総合すると、以下のSQL文で、1度に望むデータを取得できるはずです。

SELECT
  ttbl1.hoge,
  ttbl1.var,
  ttbl2.date,
  ttbl2.cost
FROM testtable2 AS ttbl2
LEFT OUTER JOIN testtable AS ttbl1
  ON ttbl2.date = ttbl1.date
WHERE ttbl2.date = ?


ただし、このSQL文は WHERE句と ON句の両方でdateカラムだけを使用しているため、両テーブルに条件に該当するdateを持つレコードが複数ある場合、それらの直積を返してしまいます。
(この問題は、質問欄に追記いただいた INNER JOIN 付きの SQL文も同様です)

ご自分でも気づいていない結合条件などが他にないか、よく確かめてみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/09 15:51

    なるほど、testtable2のほうを優先させる?みたいなことですよね。
    調査不足でした。。しかしながら的確な回答ありがとうございます。
    直積・・・?片方のテーブルはdateの値が重複して存在しないので問題ないかと思います。
    改めてありがとうございます。

    キャンセル

+1

「testtable2 にあってtesttable にないデータが有り得る」という状況のようなので、testtable2を基準に「外部結合」を使って1つのSQLにするのが最適の方法かと思います。
参考:逆引きSQL構文集 - テーブルを外部結合する

その方法に関しては他に回答があるので、あえて別SQLで行うことに拘った方法を提示しておきます。

//まずresultの結果でlistを作る
while (result.next()) {
    aaaEntity entity = new aaaEntity();

    entity.setDate(result.getString("date"));
    entity.setHoge(result.getString("hoge"));
    entity.setVar(result.geString("var"));
    list.add(entity);
}

while (result2.next()) {
    aaaEntity entity1 = null;
    aaaEntity entity2 = new aaaEntity();

    entity2.setDate(result2.getString("date"));
    entity2.setCost(result2.getString("cost"));

    for(int i=0; i<list.size(); i++){
        //要素を1つ取得
        entity1 = list.get(i);

        //entity1の日付がentity2の日付と同じかチェック
        if(entity2.getDate().equals(entity1.getDate())){
            //一致したら、entity1にentity2の持つデータをセット
           entity1.setCost(entity2.getCost()) ;

           break;
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/09 15:55

    なるほど、敢えて同じ内容のデータを登録させることで関連性ができるんですね。
    考え方として今後の参考にします。ありがとうございます。

    キャンセル

0

意図がわかっておらず間違っているかもしれませんが、

aaaEntity entity = new aaaEntity();


これをwhileの外に配置すればどうでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/09 13:25

    それ外に出したら初期化されないのでうまくリスト作れないと思うんです。

    キャンセル

0

最終的に纏めあげるようなことをして

ここが本件のポイントだと思います。testtableとtesttable2にある特定の行にどのような関係があるものをまとめるのかがわからないとどう纏めるのが適切なのかがお答えできません。「適当に纏める」というのでは問題が意味をなさないことになります。aiuの内容が書かれていればそれも推測できるのですが質問のプログラムにそれが含まれていないので推測ができないのです。

なお、適切に纏める方法がわかれば(aiuの条件がわかれば)おそらく1つのSQLで記述できるはず(というより1つのSQLで記述できなければならないはず)と思います。

もし2つの別々なSQL問い合わせ結果を先頭から順番に一つのaaaEntityに纏めると仮定するならそれなりにコードを書くことはできますが、その結果にあまり意味があるように思えないのですが・・・

SQL1の結果
  hoge1 var1
  hoge2 var2
SQL2の結果
  data1 cost1
  data2 cost2
=>javaのコードで以下のような結果にする?
結果
  hoge1 var1 data1 cost1
  hoge2 var2 data2 cost2

追記:
あれ・・・where句にdata=の条件がありましたね。失礼しました。
KiyoshiMotokiさんが既に回答されてますのでそちらをご覧ください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/09 15:02

    要は、頭に書いたコードで得られるlistと同じものを、作りたいということです。

    キャンセル

  • 2016/11/09 15:06

    コードに書かれてる内容で概ね合ってるような気はします。
    SQLを一つにしてしまうと、どちらかのテーブルにデータがなかった場合どちらも取得できなくなるのでそれはしたくないです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる