我正在尝试为我的 Grails 应用程序编写一个查询,该应用程序选择所有Apple
与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 中,所需的查询将仅返回“Apple 1”,因为Banana
与“Apple 2”相关的所有实例都通过“Cherry”实例的某种组合与“Orange 1”无关。
在下面显示的场景 2 中,所需查询将返回“Apple 1”和“Apple 2”,因为Banana
与“Apple 2”相关的所有实例都通过“Cherry”实例的某种组合与“Orange 1”相关.
这是我一直在使用的查询:
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 返回“Apple 1”和“Apple 2”。
更新#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