需要将 LEFT JOIN 转换为 JPQL
想象一下以下问题: 有人想买一篮子水果,里面有来自非洲和南美的绿色水果,但没有来自非洲的红色水果。
为此,我们考虑以下类:
class Basket
{
int id;
Collection<Fruit> fruits;
}
class Fruit
{
int id;
int basketId;
String origin
Color color;
}
映射将为 MxM。 Fruit 的目的是没有 Basket 对象,但如果需要的话我可以实现它。
对于本机 SQL,我将使用:
SELECT *
FROM
Basket b
JOIN
(
SELECT DISTINCT basketId
FROM Fruit
WHERE color='green' AND (origin='Africa' OR origin='South America')
) f1 ON (b.id=f1.basketId)
LEFT JOIN
(
SELECT DISTINCT basketId
FROM Fruit
WHERE color='red' AND (origin='Africa')
) f2 ON (b.id=f2.basketId)
WHERE f2.basketId IS NULL
JPQL 中的查询是什么?
我已经尝试过以下操作:
SELECT b
FROM Basket b
WHERE
b.id IN (
SELECT f1.basketId FROM Fruit f1
WHERE f1.color='green' AND (f1.origin='Africa' OR f1.origin='South America')
) AND
b.id NOT IN (
SELECT f2.basketId FROM Fruit f2
WHERE f2.color='red' AND (origin='Africa'))
但是这个查询花费了 12000 毫秒而不是 50 毫秒。 (这只是一个简单的例子。真正的表有大约 750000 个“水果”和 10000 个“篮子”,每个篮子有更多的字段。)
提前致谢
Gerald
immagine following problem:
somebody wants to buy a basket of fruit containing green fruits from Africa and South America but no red fruits from Africa.
for that we think about following classes:
class Basket
{
int id;
Collection<Fruit> fruits;
}
class Fruit
{
int id;
int basketId;
String origin
Color color;
}
the mapping will be MxM.
It is intended that Fruit has no Basket object, but if necessary i could implement it.
for Native SQL i would use:
SELECT *
FROM
Basket b
JOIN
(
SELECT DISTINCT basketId
FROM Fruit
WHERE color='green' AND (origin='Africa' OR origin='South America')
) f1 ON (b.id=f1.basketId)
LEFT JOIN
(
SELECT DISTINCT basketId
FROM Fruit
WHERE color='red' AND (origin='Africa')
) f2 ON (b.id=f2.basketId)
WHERE f2.basketId IS NULL
What will be the Query in JPQL?
i tried already following:
SELECT b
FROM Basket b
WHERE
b.id IN (
SELECT f1.basketId FROM Fruit f1
WHERE f1.color='green' AND (f1.origin='Africa' OR f1.origin='South America')
) AND
b.id NOT IN (
SELECT f2.basketId FROM Fruit f2
WHERE f2.color='red' AND (origin='Africa'))
but this query took 12000ms instead of 50 ms.
(This is just a simple example. The real Tables have around 750000 "fruits" and 10000 "baskets" with much more fields each.)
Thanks in advance
Gerald
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你可以尝试
,但我不确定它会更快。这取决于执行计划,而执行计划又取决于数据库索引。
Fruit.basketId
和Fruit.color
上应该有一个索引。You could try
But I'm not sure it would be faster. It depends on the execution plan, which depends on the database indexes. There should be an index on
Fruit.basketId
and onFruit.color
.这行得通吗?
连接可能是可选的,因此也可以是
would this work?
The join is probably optional so it could also be