Sql 用HQL查询多对多联接表

Sql 用HQL查询多对多联接表,sql,hibernate,grails,hql,gorm,Sql,Hibernate,Grails,Hql,Gorm,我需要一些关于创建hql查询的建议 情况:我有一组节点,可以为其分配可配置数量的标志。为此,我有以下类/表: 课程: class Node { String name } class Flag { String name } class NodeHasFlag { Node node Flag flag boolean value } 包含一些示例数据的结果表: Node id, name 1, 'a' 2, 'b' 3, 'c' ... Flag id, na

我需要一些关于创建hql查询的建议

情况:我有一组
节点
,可以为其分配可配置数量的
标志
。为此,我有以下类/表:

课程:

class Node {
  String name
}

class Flag {
  String name
}

class NodeHasFlag {
  Node node
  Flag flag
  boolean value
}
包含一些示例数据的结果表:

Node
id, name
1,  'a'
2,  'b'
3,  'c'
...

Flag
id, name
1,  'visible'
2,  'special'
...

NodeHasFlag
node_id, flag_id, value
1,       1,       true      // node 'a' is visible
2,       1,       false     // node 'b' is not visible
2,       2,       true      // node 'b' is special
3,       1,       false     // node 'c' is not visible
...
现在,我需要一个hql查询来获取基于标志的节点列表

比如:给我所有可见和特殊的节点

或者:给我所有
可见的
节点,并为
特殊
提供未定义的值(在
节点标记
表中没有条目)

检查单个标志很容易,但同时检查多个标志会给我带来麻烦


我正在使用Grails和Gorm,但我认为问题与标准javahibernate相同,我认为可以通过子查询解决这个问题。第一个例子可能是这样的。第二个示例需要左连接和OR为NULL的限制

    select n from Node n
        where n.id in 
            (select n2.id from Node n2 
                join n2.flags f2 
                where f2.visible = :visibleValue)
       and n.id in
            (select n3.id from Node n3
                join n3.flags f3
                where f3.special = :specialValue)

我想你可以用子查询来解决这个问题。第一个例子可能是这样的。第二个示例需要左连接和OR为NULL的限制

    select n from Node n
        where n.id in 
            (select n2.id from Node n2 
                join n2.flags f2 
                where f2.visible = :visibleValue)
       and n.id in
            (select n3.id from Node n3
                join n3.flags f3
                where f3.special = :specialValue)

您还可以发挥创意(假设NodeHasFlag从来没有相同的节点id和标志id),并尝试以下操作:

// Both visible and special
select n from Node n
   where 3 = (
     select SUM(CASE f.name WHEN 'visible' THEN 2 WHEN 'special' THEN 1 ELSE 0 END)
      from n.flags f))


稍微优化一点,但不那么直观:)

您也可以发挥创意(假设nodehassflag从来没有相同的node\u id和flag\u id),然后尝试以下操作:

// Both visible and special
select n from Node n
   where 3 = (
     select SUM(CASE f.name WHEN 'visible' THEN 2 WHEN 'special' THEN 1 ELSE 0 END)
      from n.flags f))


优化了一点,但不够直观:)

问题是HQL不支持相交或并集。您可以执行每个HQL语句,然后使列表相交。问题是HQL不支持相交或并集。您可以执行每个HQL语句,然后与列表相交。谢谢。我想这对我有帮助:-)谢谢。我认为这对我有帮助:-)谢谢你的想法,但我认为碳税的方法更可靠。@Jim Sosa-我个人对这种创造性的方法有弱点,但它们很少能在现实生活中应用到你的应用中。尽管如此,这还是很诱人的谢谢你的这个想法,但我认为碳税的方法更可靠。@Jim Sosa-我个人对这种创造性的方法有弱点,但它们很少能在现实生活中应用到你的应用中。尽管如此,这还是很诱人的