これはJPQL質問またはSQL質問かもしれませんが、それはJPA仕様のCriteriaの例を読んだことに由来しています。 JPAとCriteria APIもタグ付けしています。問題は、SQLの相関サブクエリの仕組みがわからないことだと思います。 サブクエリ・ルートの結合は、JPQLまたはSQL問合せの結果セットにどのように影響しますか?
は を含むクエリの結合条件は影響しません派生サブクエリのルートを含むジョイン注、私は言うJPA Spec. section 6.5.12, Subqueries, Example 4: A Special Case,から始めましょう。次の二つのクエリ 定義ので、セマンティクスが異なる:
CriteriaQuery<Order> q = cb.createQuery(Order.class);
Root<Order> order = q.from(Order.class);
Subquery<Integer> sq = q.subquery(Integer.class);
Root<Order> orderSub = sq.correlate(order);
Join<Order,Customer> customer = orderSub.join(Order_.customer);
Join<Customer,Account> account = customer.join(Customer_.accounts);
sq.select(account.get(Account_.balance));
q.where(cb.lt(cb.literal(10000), cb.all(sq)));
と
CriteriaQuery<Order> q = cb.createQuery(Order.class);
Root<Order> order = q.from(Order.class);
Join<Order,Customer> customer = order.join(Order_.customer);
Subquery<Integer> sq = q.subquery(Integer.class);
Join<Order,Customer> customerSub = sq.correlate(customer);
Join<Customer,Account> account = customerSub.join(Customer_.accounts);
sq.select(account.get(Account_.balance));
q.where(cb.lt(cb.literal(10000), cb.all(sq)));
これらのクエリの最初の顧客との に関連付けられていない注文を返します、一方、第二のものはそうではない。対応するJava 永続クエリ言語クエリは、次のとおりです。
SELECT o
FROM Order o
WHERE 10000 < ALL (
SELECT a.balance
FROM o.customer c JOIN c.accounts a)
と
SELECT o
FROM Order o JOIN o.customer c
WHERE 10000 < ALL (
SELECT a.balance
FROM c.accounts a)
2番目のクエリは、簡単なようだが、最初は視覚化することは困難です。
相関サブクエリについての理解は、外側のクエリに依存することです。外部クエリのデータを使用します。外部クエリとは独立していません。外部クエリから選択された行ごとに1回実行されます。
両方のクエリで、外部クエリで注文が選択されています。最初のクエリでは、外部クエリから選択した各注文については、以下のサブクエリが実行されます:
SELECT a.balance FROM o.customer c JOIN c.accounts a
直感が受注レコードに関連付けられている顧客が口座に参加していることを私に伝えます。したがって、サブクエリは、現在のOrderレコードに関連付けられている特定の顧客に関連付けられたすべてのアカウントの残高を返します。
私は間違っていますか?とてもサブクエリが注文に関連付けられた顧客の口座残高を返さない?これ、再び、と言い、
"Note that joins involving the derived subquery root do not affect the join conditions of the containing query,"
と、"The first of these queries will return Orders that are not associated with customers..."
、上記の例によると、私が間違っているようですかその代わりにどの勘定残高が返されますか?これを見て正しい方法は何ですか?私の頭がクラクラします。
あなたの 'join'は' on'節を持たないので、そのクエリに従うのは難しいです。 –
JPA 2.1仕様からまっすぐに出てくる例であるため、クエリを変更したくありません。 –