ここで紹介した方法は、サブクエリの検索条件にメインのクエリの検索結果を入れる事が出来ない。
子テーブルは最新のものを持ってくるようなパターンでは使えない。なので、そのような場合は以下の方法で行う。
子要素は最新のを常に見るといった場合、以下のようなSQLを使いたい!
SELECT ..
FROM parent INNER JOIN child
ON ……..
WHERE child.id = (SELECT MAX(id) FROM child child_sub WHERE parent.id = child_sub.parent_id)
Criteria でどうするか。
説明
まず、親
1 2 3 4 5 6 7 |
class Author { static hasMany = [books : Book] } |
そして、その子
1 2 3 4 5 6 7 8 9 |
class Book { String name Date publishDate static belongsTo = [author : Author] } |
この時、最新の publishDate を持つ、データで Book の name で ソートしたい時。
手順
サブクエリを作る
1 2 3 4 5 6 7 8 9 10 11 |
def sub = DetachedCriteria.forClass(Book, 'bk').with { // max(bk.id) setProjection(Projections.max('bk.id')) // author.id = bk.author.id add(Restrictions.conjunction() .add(Restrictions.eqProperty('this.id', 'bk.author.id'))) } |
クエリに入れる
1 2 3 4 5 |
createAlias('books', 'bk') // bk.id = ( select max(bk.id) .... instance.add(Subqueries.propertyEq('bk.id', sub)) |
後は、order するだけ
1 2 3 |
order 'bk.name', 'asc' |
子要素の name ソートしたい場合は、
1 2 3 |
<g:sortableColumn property="bk.name" title="..." params="${params}"/> |
のように、property をセットしてあげればよい。
動かないよ!!
- DetachedCriteria
- Projections
などは、以下から import してる? 同じようなのが、grails のパッケージにもかるから注意
各々以下からインポート
- import org.hibernate.criterion.Projections
- import org.hibernate.criterion.DetachedCriteria