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

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

新規登録して質問してみよう
ただいま回答率
85.35%
GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

2回答

2228閲覧

Thymeleafおいて、データをGroupingByで取得したときの表示方法

K-actus

総合スコア22

GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2021/04/07 08:24

編集2021/04/08 10:02

こんにちは。
Javaについて初学者なので拙いところもあると思いますが、よろしくお願いします。

###実現したいこと

IdNameCountry
1TaroJapan
2MikeAmerica
3LiChina
4HanakoJapan
5DaisyAmerica

データベース上に上記のようなname_listテーブルがあるとして、
これを国ごとにHTMLのテーブルで分けて表示したいとします。

###コード

Repositoryクラス

Java

1public interface NameListRepository extends JpaRepository<NameList, Integer> { 2 public static final String _query 3 = "SELECT" 4 + "*" 5 + " FROM" 6 + " name_list" 7 + " GROUP BY" 8 + " country" 9 ; 10 @Query(value = _query, nativeQuery = true) 11 List<NameList> findAll(); 12}

Controllerクラス

Java

1@Controller 2public class TestController { 3 @Autowired 4 private NameListRepository nameListRepository; 5 6 @GetMapping("/Test") 7 public String getNameList(Model model) { 8 List<NameList> NameList = nameListRepository.findAll(); 9 model.addAttribute("NameList", NameList); 10 11 return "Test"; 12 } 13}

View(Thymeleaf)

Thymeleaf

1<table th:each="group: ${NameList}"> 2<tr> 3 <th>名前</th> 4 <th>国</th> 5</tr> 6<tr th:each="item: ${group}"> 7 <td th:text="${item.Name}"></td> 8 <td th:text="${item.Country}"></td> 9</tr> 10</table> 11

###わからないところ
上記のようなHTMLでグループごとの表示が出来ると思ったのですが、
<tr th:each="item: ${group}">のところがやはり機能していないみたいで、
各テーブル内が繰り返し表示されません。

どうすれば実現できるでしょうか。
回答よろしくお願いします。

###追記
みなさんのコメントや回答で気付いたのですが、SQLでのGROUP BYとJavaでのGroupingByを混同しており、
Groupの中身を参照出来るのは後者であるためRepositoryクラスとControllerを書き換えました。

Repositoryクラス

Java

1public interface NameListRepository extends JpaRepository<NameList, Integer> { 2}

Controllerクラス

@Controller public class TestController { @Autowired private NameListRepository nameListRepository; @GetMapping("/Test") public String getNameList(Model model) { List<NameList> NameList = nameListRepository.findAll(); Map<String, List<NameList>> NameListMap = NameList.stream() .collect(Collectors.groupingBy(obj -> obj.getCountry)); model.addAttribute("NameList", NameList); return "Test"; } }

この後View(Thymeleaf)でCountryのMapごとにNameListが列挙されたTableを表示させる方法が知りたいです。
一応この記事の前半部分に似たようなことが書いてあり、試してみましたが表示されなくなりました。
https://teratail.com/questions/138795

補足情報

Eclipse 2020 Java FullEdition
AmazonCorretto jdk15.0.2_7
SpringBoot 2.4.3
MySQL 8.0.23
Windows10 Pro 1909

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/04/07 09:43

そもそもcountryだけgroup by したらエラーになりませんか? MySQLは緩いんでしたっけ。
K-actus

2021/04/07 23:57

そのエラーというのはどこで起きるんですか? パッと見起きていないのですが・・・
gpsoft

2021/04/08 03:00

MySQLは緩いです。設定次第でエラーになったり、ならなかったりすると思います。「MySQL sql_mode ONLY_FULL_GROUP_BY」でググってみてください。 エラーにならなかったとしても、今のクエリーだと、3行しか返ってこないと思います。クライアントツール(例えばMySQL Workbenchとかmysqlコマンドとか)でDBに接続して、まずはSELECT文が期待通りの結果を返すかどうか確認することをオススメします。
K-actus

2021/04/08 07:20 編集

確かに返ってきませんでした。 そもそも集計関数を使用しないこの場合でGROUP BYを使うこと自体が見当違いですか?
m.ts10806

2021/04/08 07:22 編集

group by使うと取得項目は何かしらで集約されているべきという制約があるので、他のDBだとエラーになります。
guest

回答2

0

ベストアンサー

国毎に集約されたデータを作らないとダメなので、
DBでやるか取ってきたデータを自分で集約するかの2択だと思います。

自分で集約する場合、streamのgroupbyを使うと便利です。

Java

1List<NameList> NameList = nameListRepository.findAll(); 2Map<String, List<NameList>> map = NameList.stream() 3 .collect(Collectors.groupingBy(obj -> obj.Country));

投稿2021/04/08 08:03

Luice

総合スコア771

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

K-actus

2021/04/08 09:24 編集

おそらくその集約する方法が私のやりたいことに一番近いのですが、 本質問にもある通りその後Map<String,List<NameList>>をViewで表示するにはどうすればいいのでしょうか・・・
Luice

2021/04/08 23:18

集約したmapをmodelに追加して、th:each でEntrySetを取得して さらにvalue(List<NameList>型)をth:eachでループさせればいいだけです。
K-actus

2021/04/09 01:15

出来ました! ありがとうございます。
K-actus

2021/04/09 07:46

この場合MapのKEYはどうやって決まっているんですか?
Luice

2021/04/09 08:13

"java stream collectors groupingby" で検索かければ色々と情報が出てきますよ。
K-actus

2021/04/09 09:28

調べてもKeyがどう決まるかについてはわからなかったので質問しました・・・。
guest

0

考え方だけ。
地道なやり方ですが、「Country」をキーにしてその一覧をマップで作るという手があります。

group byしてCountryだけselectしてくる

ループしてCountryをwhereの条件として同じテーブルにselectしてNameのみを取得

取得したName群をCountryをキーにしたマップに保存

viewに渡して表示

何回もselectかけることになりますが、現状だとこうなります。

Countryは別のテーブルに持ったほうがいいように思います。Group byが不要になるので多少はパフォーマンスもよくなります。

投稿2021/04/08 07:28

m.ts10806

総合スコア80875

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

K-actus

2021/04/08 07:53

クエリだけだとそれしか方法がないように思えますが、SpringBootにGROUP BYでグループ分けされた中身のデータを列挙する機能はないんですか?
m.ts10806

2021/04/08 08:01

クエリだけでは無理なのでほしいデータを適宜とってきてマップにするロジックを書こうという話をしています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問