Apple
のインスタンスに「関連する」すべてのインスタンスを選択するGrailsアプリケーションのクエリを作成しようとしていますOrange
。ここで、「関連する」という言葉は、のインスタンスに関連付けられているすべてのインスタンスが、関係Banana
するインスタンスに関連付けられているインスタンスのApple
いくつかの組み合わせに関連付けられていることを意味しCherry
ますOrange
。私はここで質問を見てきましたが、私の質問はもう少し複雑で、与えられた答えを私の問題に適用する方法がわかりません。
これが私が扱っているクラスです:
class Apple {
static hasMany = [ bananas: Banana ]
}
class Banana {
}
class Cherry {
static hasMany = [ bananas: Bannna ]
}
class Orange {
static hasMany = [ cherries: Cherry ]
}
次のような画像形式で:
以下に示すシナリオ1では、Banana
「Apple 2」に関連するすべてのインスタンスが「Cherry」のインスタンスのいくつかの組み合わせを通じて「Orange1」に関連していないため、目的のクエリは「Apple1」のみを返します。
Banana
以下に示すシナリオ2では、「Apple2 」に関連するすべてのインスタンスが「Cherry」のインスタンスのいくつかの組み合わせを通じて「Orange1」に関連しているため、目的のクエリは「Apple1」と「Apple2」を返します。 。
これが私が扱ってきたクエリです:
Apple.executeQuery(
"SELECT DISTINCT apples
FROM Apple apples
INNER JOIN apples.banannas banannas
WHERE banannas IN(
SELECT DISTINCT banannas
FROM Cherry cherries
INNER JOIN cherries.banannas banannas
WHERE cherries IN(
SELECT DISTINCT cherries
FROM Orange orange
INNER JOIN orange.cherries cherries
WHERE orange =:myOrange
)
)
ORDER BY apples.id ASC",
myOrange: myOrange
)
問題は、私のクエリがシナリオ1と2の両方で「Apple1」と「Apple2」を返すことです。
更新#1:
要求に応じて、HQLクエリによって生成されたSQLは次のとおりです。フルーティーな難読化でごめんなさい<<<しゃれ
SELECT DISTINCT apple0_.id AS id10_,
apple0_.version AS version10_,
apple0_.description AS descript3_10_,
apple0_.apple_priority_type_id AS apple4_10_,
apple0_.apple_status_type_id AS apple5_10_,
apple0_.internal_need_date AS internal6_10_,
apple0_.name AS name10_
FROM apple apple0_
INNER JOIN apple_priority_type applepri1_
ON apple0_.apple_priority_type_id = applepri1_.id
INNER JOIN apple_status_type applesta2_
ON apple0_.apple_status_type_id = applesta2_.id
INNER JOIN apple_banana banana3_
ON apple0_.id = banana3_.apple_bananas_id
INNER JOIN banana banana4_
ON banana3_.banana_id = banana4_.id
WHERE banana4_.id IN (SELECT DISTINCT banana7_.id
FROM cherry plum5_
INNER JOIN cherry_banana banana6_
ON plum5_.id = banana6_.cherry_bananas_id
INNER JOIN banana banana7_
ON banana6_.banana_id = banana7_.id
WHERE plum5_.id IN (SELECT DISTINCT plum10_.id
FROM orange orange8_
INNER JOIN orange_cherry
plum9_
ON
orange8_.id = plum9_.orange_cherrys_id
INNER JOIN cherry plum10_
ON
plum9_.cherry_id = plum10_.id
WHERE orange8_.id = 248))
ORDER BY apple0_.id ASC
LIMIT 100
更新#2:
私は実際にこれをHQLで機能させる方法を持っていますが、他のタイプのインスタンスに関連するすべてのタイプを見つけている他の場所にあるようなワンライナーではありません。これが私の回避策です:
def bananas= myOrange.cherries.bananas.flatten().unique()
def apples = Apple.getAll().collectMany{ !it.bananas.isEmpty() && bananas.containsAll( it.bananas ) ? [ it ] : [] }.flatten().unique()
namedParams.put( "apples", apples )
if( !apples.isEmpty() ) {
apples = Apple.executeQuery( "SELECT DISTINCT apples FROM Apple apples WHERE apples IN(:apples) ${additionalQuery} ORDER BY ${sortname} ${sortorder}", namedParams )
}
return apples