Grails 确定列表是否是另一个列表HQL的子集

Grails 确定列表是否是另一个列表HQL的子集,grails,hql,Grails,Hql,我正在尝试为我的Grails应用程序编写一个查询,该查询选择与Orange实例“相关”的Apple的所有实例。在这里,“相关”一词是指与Apple实例相关联的Banana的所有实例都与与我们关注的Orange实例相关联的Cherry实例的一些组合相关联。我已经看了这个问题,但是我的问题有点复杂,我不知道如何将给定的答案应用到我的问题上 以下是我正在处理的类: class Apple { static hasMany = [ bananas: Banana ] } class Banan

我正在尝试为我的Grails应用程序编写一个查询,该查询选择与
Orange
实例“相关”的
Apple
的所有实例。在这里,“相关”一词是指与
Apple
实例相关联的
Banana
的所有实例都与与我们关注的
Orange
实例相关联的
Cherry
实例的一些组合相关联。我已经看了这个问题,但是我的问题有点复杂,我不知道如何将给定的答案应用到我的问题上

以下是我正在处理的类:

class Apple {
    static hasMany = [ bananas: Banana ]
}

class Banana {
}

class Cherry {
    static hasMany = [ bananas: Bannna ]
}

class Orange {
    static hasMany = [ cherries: Cherry ]
}
以如下所示的图片形式:

在下面所示的场景1中,所需的查询将只返回“Apple 1”,因为与“Apple 2”相关的
Banana
的所有实例都不会通过“Cherry”实例的某些组合与“Orange 1”相关

在下面所示的场景2中,所需的查询将返回“Apple 1”和“Apple 2”,因为与“Apple 2”相关的
Banana
的所有实例都通过“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中都返回“apple1”和“apple2”

更新#1:


根据请求,以下是HQL查询生成的SQL。很抱歉让人困惑,因为如果你的苹果和香蕉至少有一种关系,它总是会回来的

select
    distinct apple0_.id as id0_,
    apple0_.version as version0_ 
from
    apple apple0_ 
inner join
    apple_banana bananas1_ 
where bananas1_.banana_id in (1,2,3)
你需要做的是从你的结果中排除不存在的苹果与你的樱桃相关的香蕉。您必须查看您的数据库是否具有类似oracle减号的功能

编辑:此查询将从列表中删除含有不在樱桃香蕉中的香蕉的苹果

注意:我没有检查这个的性能

  SELECT DISTINCT apples
    FROM Apple apples
    INNER JOIN apples.bananas bananas
    WHERE bananas IN(
        SELECT DISTINCT bananas
        FROM Cherry cherries
        INNER JOIN cherries.bananas bananas
        WHERE cherries IN(
            SELECT DISTINCT cherries
            FROM Orange orange
            INNER JOIN orange.cherries cherries
            WHERE orange =:myOrange
        )
    )
  and apples not in (
    SELECT DISTINCT apples
      FROM Apple apples
     INNER JOIN apples.bananas bananas
      WHERE bananas NOT IN(
        SELECT DISTINCT bananas
          FROM Cherry cherries
          INNER JOIN cherries.bananas bananas
          WHERE cherries IN(
            SELECT DISTINCT cherries
            FROM Orange orange
            INNER JOIN orange.cherries cherries
            WHERE orange = :myOrange
          )
      )
    )

这是因为如果你的苹果和香蕉至少有一个关系,它总是会回来的

select
    distinct apple0_.id as id0_,
    apple0_.version as version0_ 
from
    apple apple0_ 
inner join
    apple_banana bananas1_ 
where bananas1_.banana_id in (1,2,3)
你需要做的是从你的结果中排除不存在的苹果与你的樱桃相关的香蕉。您必须查看您的数据库是否具有类似oracle减号的功能

编辑:此查询将从列表中删除含有不在樱桃香蕉中的香蕉的苹果

注意:我没有检查这个的性能

  SELECT DISTINCT apples
    FROM Apple apples
    INNER JOIN apples.bananas bananas
    WHERE bananas IN(
        SELECT DISTINCT bananas
        FROM Cherry cherries
        INNER JOIN cherries.bananas bananas
        WHERE cherries IN(
            SELECT DISTINCT cherries
            FROM Orange orange
            INNER JOIN orange.cherries cherries
            WHERE orange =:myOrange
        )
    )
  and apples not in (
    SELECT DISTINCT apples
      FROM Apple apples
     INNER JOIN apples.bananas bananas
      WHERE bananas NOT IN(
        SELECT DISTINCT bananas
          FROM Cherry cherries
          INNER JOIN cherries.bananas bananas
          WHERE cherries IN(
            SELECT DISTINCT cherries
            FROM Orange orange
            INNER JOIN orange.cherries cherries
            WHERE orange = :myOrange
          )
      )
    )

您可以发布Hibernate生成的sql查询吗?@SérgioMichels根据请求添加了生成的sql。您可以发布Hibernate生成的sql查询吗?@SérgioMichels根据请求添加了生成的sql。对,但是如何使用HQL one liner实现这一点?事实上,我主要使用HQL,但它并不像我希望的那样干净/高效。我构建的用于查找与另一种类型的实例关联的所有类型的函数假定查询将使用HQL运行,因此我可以对结果使用分页。参见更新#2Ok,我已经用查询进行了更新,这是我用“减号”表示的结果。对,但是我如何用HQL单行程序实现这一点呢?事实上,我主要使用HQL,但它并不像我希望的那样干净/高效。我构建的用于查找与另一种类型的实例关联的所有类型的函数假定查询将使用HQL运行,因此我可以对结果使用分页。请参见更新#2Ok,我已经用查询进行了更新,这是我用“减号”表示的结果。