私は2つのクラスを持っています
Quiz{
String name
static hasMany[tags:Tag]
}
Tag{
String tag
}
基準ビルダーを使用して、grails で次のクエリを作成するにはどうすればよいですか?
select count(tag_id),tag from quiz_tag
left outer join tag on tag_id=id
group by tag_id,tag
私は2つのクラスを持っています
Quiz{
String name
static hasMany[tags:Tag]
}
Tag{
String tag
}
基準ビルダーを使用して、grails で次のクエリを作成するにはどうすればよいですか?
select count(tag_id),tag from quiz_tag
left outer join tag on tag_id=id
group by tag_id,tag
here で説明されているように、多対多テーブルをドメイン クラスにマップする場合は、基準クエリを使用してこれを行うことができます。
class QuizTag {
Quiz quiz
Tag tag
...
}
def counts = QuizTag.withCriteria {
projections {
groupProperty('tag')
rowCount()
}
}
counts
変数はリストのList
になり[Tag object, count of the Tag]
ます。
各タグがクイズで何回使用されているかを知りたいようです。ドメインクラスを定義したように定義すると、ミドルテーブルのquiz_tagが得られ、行SQLを使用して、この質問の結果を見つけることができます。
ただし、タグから結合テーブルにアクセスできないため、Critera Builder、つまりHibernateではこれは不可能のようです。クイズは持っているので、あなたはクイズからそれを行うことができますhasMany[tags:Tag]
次のように変更すると、タグから結合テーブルにアクセスできます。
Tag{
String tag
static belongsTo = Quiz
static hasMany[quizes:Quiz]
}
データベースモデルは同じままですが、Hibernateはタグから結合テーブルに移動できるようになりました。このHQLクエリを試すと、クイズのタグと出現回数がわかります。
Tag.executeQuery("SELECT t, count(q) FROM Tag t JOIN FETCH t.quizes q GROUP BY t")
HQLだけの方が簡単だと思いますが、基準ビルダーでも、サポートされている場合はグループ化にsqlGroupProjectionを使用することで実行できると思います。
顧客がストアに多くの関連付けを持っているという同様の問題がありました。次のコードを使用して、条件を使用して店舗をカウントすることができました。
class Customer {
static hasMany = [stores : Store]
...
}
class Store {
Customer customer
...
}
def c = Store.createCriteria()
def results = c.list {
customer {
'in'("customerNumber",['1-1','1-2','1-3'])
}
projections {
sqlGroupProjection 'customer_id, count(customer_id) as numberOfStores', 'customer_id', ['customer_id', 'numberOfStores'], [INTEGER, INTEGER]
}
}
結果: [[1, 3], [2, 3]]
返されるフィールドは [customer.id, numberOfStores] です。