具有1:n关系的SQL查询,找到具有两个匹配子对象的所有实体匹配

时间:2018-07-18 16:01:50

标签: java sql database jpa

我有一个简单的父子关系(1:n,@ OneToMany),由JPA映射。

一个孩子(除其他外)具有以下属性:

  • 用户
  • 类型

我现在要查找所有父元素,这些父元素至少具有以下两个子元素:

  • 第一个具有user ='user1'且类型='type1'AND的孩子
  • 第二个孩子,其用户='user2',类型=='type2' 或
  • 第一个具有user ='user1'和type ='type2'AND的孩子
  • 第二个用户为user ='user2'且类型为'type1'

例如一个实体可以有10个孩子,但其中两个必须符合上述条件。

您是否有任何使用SQL / JPA Criteria API进行处理的提示?

EXISTS子句是解决之道吗?

SELECT * FROM Parent parent
WHERE EXISTS (SELECT child FROM Child WHERE (child.user = 'user1' AND    child.type = 'type1' OR ...) AND child.id=parent.id)
OR
EXISTS (SELECT child FROM Child WHERE (child.user = 'user1' AND child.type = 'type2' OR ...) AND child.id=parent.id)

感谢您的帮助!

更新: 父级代表“邮件”,子级关系代表邮件的发送者和接收者,如下所示:

Parent Table (Mail):
|id | subject     |
|1  | Hello World |
|2  | Foo Bar     |
|3  | Example     |
|4  | Test        |

Child Table:
|id | user      | type     |
|1  | user1@mail| SENDER   |
|1  | user2@mail| RECEIVER |
|1  | user3@mail| RECEIVER |
|2  | user1@mail| SENDER   |
|2  | user4@mail| RECEIVER |
|2  | user5@mail| RECEIVER |
|3  | user2@mail| SENDER   |
|3  | user1@mail| RECEIVER |
|3  | user5@mail| RECEIVER |
|4  | user3@mail| SENDER   |
|4  | user1@mail| RECEIVER |
|4  | user2@mail| RECEIVER |

子表的主键是(id,user,type)的组合键。 id列是1:n关系的连接列。

我想查找所有由user1发送并由user2接收的邮件,反之亦然,例如在两个用户之间交换的邮件。

示例输入:“ user1”,“ user2” 结果:邮件1和3,而不是邮件4,因为在邮件4中,两个用户都是收件人。

1 个答案:

答案 0 :(得分:0)

一个巧妙的技巧是计算这样的父母拥有的唯一孩子的数量:

SELECT * 
FROM   parent p
WHERE  EXISTS (SELECT   child_id
               FROM     child c
               WHERE    user IN ('user1', 'user2') AND
                        type IN ('type1', 'type2') AND
                        c.parent_id = p.id
               GROUP BY child_id
               HAVING   COUNT(DISTINCT user) = 2 AND
                        COUNT(DISTINCT type) = 2)