14

これはサンプル エンティティです。

public class Account{

   @Id
   Long id
   Double remaining;
   @ManyToOne
   AccountType type
}

public class AccountType{
   @Id
   Long id;
   String name;
}  

ここで、次のように Join を使用して基準クエリを作成します。

CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createquery();
Root<Account> accountRoot = criteriaQuery.from(Account.class);
Join<Account, AccountType> typeJoin = accountRoot.join(Account_.type);

criteriaQuery.multiSelect(
    typeJoin,
    criteriaBuilder.sum(accountRoot.get(Account_.remaining))
);

criteriaQuery.groupBy(typeJoin);
Query query = getEntityManager().createQuery(criteriaQuery);
query.getResultList();  

上記のコードは、次のような Sql コマンドを生成します。

select accType.id, accType.name, sum(acc.remaining)
from account acc join accType on acc.accounttype_id = accType.id
group by accType.id  

上記のコードは PosgreSQL では機能しますが、Oracle では実行できません。これは、group by 句に表示されない accType.name を選択するためです。

更新
私の質問はあなたにとって明確ではないと思います。私の質問は、.NET での PostgreSQL や Oracle の動作に関するものではありませんgroup by。私の質問はこれです:
私はtypeJoiningroup by句を使用します(これは、休止状態が AccountType のすべてのフィールドを in で使用することを期待することを意味しますgroup by)が、なぜ休止状態が単に ID フィールドを on で使用するのgroup byですか? ID フィールドのみを使用するgroup by場合は、次のステートメントを使用できます。

criteriaQuery.groupBy(typeJoin.get(AccountType_.id)) ;
4

2 に答える 2

4

GROUP BY を使用する場合、Oracle では、選択リスト内のすべての列が GROUP BY に含まれている必要があります。
PostgreSQL も同じですが、主キーでグループ化する場合は、任意の列を選択できます。

オラクルのドキュメントから

GROUP BY 句を含むクエリでは、選択リストの要素は、集計関数、GROUP BY 式、定数、またはこれらのいずれかを含む式にすることができます。

PostgreSQL ドキュメントから

GROUP BY が存在する場合、または集計関数が存在する場合、SELECT リスト式がグループ化されていない列を参照することは有効ではありません。グループ化されていない列に対して返される可能性のある値は 1 つではありません。グループ化された列 (またはそのサブセット)が、グループ化されていない列を含むテーブルの主キーである場合、機能的な依存関係が存在します。

于 2015-01-05T21:33:14.413 に答える