如何在 JPA 中为 MySQL 编写自连接
How to write a self join in JPA for MySQL
我有一个名为 table 的组,其中包含四个 [相关] 列; id、parent_id、activated_date 和 type。 parent_id 和 activated_date 可以为空,如果一个组在今天之前有一个 activated_date,属于类型 A,或者它的 parent 组被激活,则该组被认为是激活的.
id
parent_id
activated_date
type
1
2020-01-01
typeA
2
3
typeB
3
2020-01-01
typeC
我正在尝试编写一个查询来列出所有已激活的组,但我 运行 遇到了一个非常令人困惑的问题。 (注意:我正在使用 CASE 语句,因为在 JPA 中,SELECT 子句中不允许条件表达式,但它们在 CASE 表达式中)
如果我的 WHERE 子句如下所示:
(CASE
WHEN
g.activated_date is not null AND
g.activated_date < CURDATE()
THEN TRUE
WHEN
g.group_type = 'typeA'
THEN TRUE
ELSE FALSE
END) = TRUE
然后我找到 9000 个激活的组(如果我更改为 FALSE,则找到 1000 个停用的组)。这是意料之中的,一共10000组。
但是当我添加一个附加条件来检查 parent 的状态时(注意:这不需要递归,在这个用例中组不能有 'grandparents'):
(CASE
WHEN
g.activated_date is not null AND
g.activated_date < CURDATE()
THEN TRUE
WHEN
g.group_type = 'typeA'
THEN TRUE
WHEN
(g.parent.activated_date is not null AND g.parent.activated_date < CURDATE()) OR
(g.parent.group_type = 'typeA')
THEN TRUE
ELSE FALSE
END) = TRUE
然后我突然发现我有 8500 个激活的组(和 750 个停用的)。我无法解释丢失的 750 个组;我做错了什么吗?
您的完整查询不明确,但如果 'g' 个实例没有父项,它们将从查询结果中删除。您需要对此关系使用左联接才能将它们包含在结果中。
"select <your select clause> where G g left join g.parent parent where <your Where clause>"
在 select 或 where 子句中使用 g.parent 的地方,您只需使用 parent
。所以
(CASE
WHEN
g.activated_date is not null AND
g.activated_date < CURDATE()
THEN TRUE
WHEN
g.group_type = 'typeA'
THEN TRUE
WHEN
parent is not null AND
((parent.activated_date is not null AND parent.activated_date < CURDATE()) OR
(parent.group_type = 'typeA'))
THEN TRUE
ELSE FALSE
END) = TRUE
我有一个名为 table 的组,其中包含四个 [相关] 列; id、parent_id、activated_date 和 type。 parent_id 和 activated_date 可以为空,如果一个组在今天之前有一个 activated_date,属于类型 A,或者它的 parent 组被激活,则该组被认为是激活的.
id | parent_id | activated_date | type |
---|---|---|---|
1 | 2020-01-01 | typeA | |
2 | 3 | typeB | |
3 | 2020-01-01 | typeC |
我正在尝试编写一个查询来列出所有已激活的组,但我 运行 遇到了一个非常令人困惑的问题。 (注意:我正在使用 CASE 语句,因为在 JPA 中,SELECT 子句中不允许条件表达式,但它们在 CASE 表达式中)
如果我的 WHERE 子句如下所示:
(CASE
WHEN
g.activated_date is not null AND
g.activated_date < CURDATE()
THEN TRUE
WHEN
g.group_type = 'typeA'
THEN TRUE
ELSE FALSE
END) = TRUE
然后我找到 9000 个激活的组(如果我更改为 FALSE,则找到 1000 个停用的组)。这是意料之中的,一共10000组。
但是当我添加一个附加条件来检查 parent 的状态时(注意:这不需要递归,在这个用例中组不能有 'grandparents'):
(CASE
WHEN
g.activated_date is not null AND
g.activated_date < CURDATE()
THEN TRUE
WHEN
g.group_type = 'typeA'
THEN TRUE
WHEN
(g.parent.activated_date is not null AND g.parent.activated_date < CURDATE()) OR
(g.parent.group_type = 'typeA')
THEN TRUE
ELSE FALSE
END) = TRUE
然后我突然发现我有 8500 个激活的组(和 750 个停用的)。我无法解释丢失的 750 个组;我做错了什么吗?
您的完整查询不明确,但如果 'g' 个实例没有父项,它们将从查询结果中删除。您需要对此关系使用左联接才能将它们包含在结果中。
"select <your select clause> where G g left join g.parent parent where <your Where clause>"
在 select 或 where 子句中使用 g.parent 的地方,您只需使用 parent
。所以
(CASE
WHEN
g.activated_date is not null AND
g.activated_date < CURDATE()
THEN TRUE
WHEN
g.group_type = 'typeA'
THEN TRUE
WHEN
parent is not null AND
((parent.activated_date is not null AND parent.activated_date < CURDATE()) OR
(parent.group_type = 'typeA'))
THEN TRUE
ELSE FALSE
END) = TRUE