3

次の表がありますsession

sessionid | user_id | begin (timestamp)
----------+---------+-------------------
     1    |    A    |  1234
     2    |    B    |  4567
     3    |    A    |  8912
     4    |    C    |  3456

テーブルは、ユーザーのセッションに関する情報を提供します。基本的に、セッションはユーザーがログインに成功したときです。

ここで、最近ログインしたユーザーのリストを取得したいと思います。ユーザーが複数のログインを持っている場合 (この表で 2 回以上発生している場合)、最新のタイムスタンプを使用します。最新のユーザーがリストの一番上になるように、リストはログイン時間順に並べる必要があります。

次の SQL クエリを使用して、これを解決しました。

SELECT s.user_id, MAX(begin) -- MAX(begin) can be left out, results are the same
FROM session s
GROUP BY s.user_id
ORDER BY MAX(s.begin) DESC

ただし、私のアプリケーションでは、これに JPA クエリを使用することになっています。そこで、これを次の JPA クエリに変換しました。

SELECT s.user
FROM Session s
GROUP BY s.user
ORDER BY MAX(s.begin) DESC

User はセッション内のエンティティであるため、ここでは user_id ではなくユーザーを選択します。Hibernate も使用しています。このクエリを実行すると、次のエラーが発生します。

ERROR [org.hibernate.util.JDBCExceptionReporter] ERROR: column "user1_.id" must appear in the GROUP BY clause or be used in an aggregate function

Hibernate でのこの動作に関するバグの説明を見つけました。

代わりにを使用してもs.user.id問題なく動作しますが、ID しか得られず、ユーザー オブジェクトが必要です。

最初にユーザーIDを取得してからデータベースでユーザーエンティティを見つけることで回避策を作成しましたが、これには追加のデータベース呼び出しが必要であり、1つのクエリ内で実行できることがわかっているため、パフォーマンスが悪いようです。

この問題を解決するには?

アプリケーションで SQL クエリを直接使用することは許可されていません。JPA クエリ アプローチを使用して行う必要があります。

4

0 に答える 0