以下问题: 有人想从非洲和南美洲购买一篮子含有绿色水果的水果,但没有来自非洲的红色水果。
为此我们考虑以下课程:
class Basket
{
int id;
Collection<Fruit> fruits;
}
class Fruit
{
int id;
int basketId;
String origin
Color color;
}
映射将是MxM。 Fruit没有Basket对象,但如果有必要,我可以实现它。
对于Native 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个“篮子”,每个都有更多的字段。)
提前致谢
杰拉德
答案 0 :(得分:0)
你可以尝试
select b from Basket b where
exists (select f.id from Fruit f where f.basket = b and f.color = 'green')
and not exists (select f.id from Fruit f where f.basket = b and f.color = 'red')
但我不确定它会更快。它取决于执行计划,这取决于数据库索引。 Fruit.basketId
和Fruit.color
上应该有一个索引。
答案 1 :(得分:0)
这会有用吗?
select b from Basket b join b.fruits f where f.color = 'green' and not f.color = 'red';
连接可能是可选的,因此也可以是
select b from Basket b where b.fruits.color = 'green' and not b.fruits.color = 'red';