如何select 最贵的物品公关。在 Hibernate HQL 中搁置?
How to select the most expensive item pr. shelf in Hibernate HQL?
我现在头撞墙了。通常我会在 FROM 子句中使用子查询来解决这个问题,但是这在 HQL 中是不允许的。
我做了一个简单的例子,希望你能帮助我。
鉴于我有以下表格:
CREATE TABLE PUBLIC.SHELF
(id INTEGER NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE PUBLIC.ITEM
(id INTEGER NOT NULL,
price INTEGER NOT NULL,
description VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE PUBLIC.SHELF_ITEMS
(shelf_id INTEGER NOT NULL,
item_id INTEGER NOT NULL,
PRIMARY KEY (shelf_id, item_id)
);
从这里我想 select 最昂贵的项目公关。架子。
我可以通过查询以下语句来完成:
SELECT
shelf.id,
MAX(item.price)
FROM
PUBLIC.SHELF as shelf
INNER JOIN PUBLIC.SHELF_ITEMS as shelfitems ON shelf.id = shelfitems.shelf_id
INNER JOIN PUBLIC.ITEM as item ON item.id = shelfitems.item_id
GROUP BY shelf.id;
不过还有一个要求! - 我还希望同一结果集中的项目 ID 和描述。
所以我想要这样的东西:
SELECT
shelf.id,
item.id,
item.description,
MAX(item.price)
FROM
PUBLIC.SHELF as shelf
INNER JOIN PUBLIC.SHELF_ITEMS as shelfitems ON shelf.id = shelfitems.shelf_id
INNER JOIN PUBLIC.ITEM as item ON item.id = shelfitems.item_id
GROUP BY shelf.id;
然而,这导致了一个错误,指出我需要在 GROUP BY 子句中添加 item.id,当我添加它时,我得到了所有行。
好像我缺少一些条件,说明我只想要最贵的 selected。
SELECT
shelf.id,
item.id,
item.description,
item.price
FROM
shelf shelf
INNER JOIN shelf_items shelfitems ON shelf.id = shelfitems.shelf_id
INNER JOIN item item ON item.id = shelfitems.item_id
WHERE
item.price = (
SELECT
MAX(item_inner.price)
FROM
shelf_items shelfitems_inner
INNER JOIN item item_inner ON item_inner.id = shelfitems_inner.item_id
WHERE
shelf.id = shelfitems_inner.shelf_id
)
纯 HQL/JPQL 解决方案返回实体,假设映射正确完成,Shelf
在 多对多 和 Item
:
@SuppressWarnings("unchecked")
public Map<Shelf, Item> getShelvesWithMaxItemPrice(){
Query query = entityManager.createQuery("SELECT sh, it FROM Shelf sh join sh.items it WHERE it.price = "
+ "(SELECT MAX(itInner.price) FROM Item itInner join itInner.shelves shInner WHERE shInner.id = sh.id)");
List<Object[]> queryResults = query.getResultList();
Map<Shelf, Item> results = new LinkedHashMap<>();
for(Object[] row: queryResults) {
results.put((Shelf) row[0], (Item) row[1]);
}
return results;
}
这将生成与 Ashutosh A 的答案相同的 SQL。
我现在头撞墙了。通常我会在 FROM 子句中使用子查询来解决这个问题,但是这在 HQL 中是不允许的。 我做了一个简单的例子,希望你能帮助我。
鉴于我有以下表格:
CREATE TABLE PUBLIC.SHELF
(id INTEGER NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE PUBLIC.ITEM
(id INTEGER NOT NULL,
price INTEGER NOT NULL,
description VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE PUBLIC.SHELF_ITEMS
(shelf_id INTEGER NOT NULL,
item_id INTEGER NOT NULL,
PRIMARY KEY (shelf_id, item_id)
);
从这里我想 select 最昂贵的项目公关。架子。 我可以通过查询以下语句来完成:
SELECT
shelf.id,
MAX(item.price)
FROM
PUBLIC.SHELF as shelf
INNER JOIN PUBLIC.SHELF_ITEMS as shelfitems ON shelf.id = shelfitems.shelf_id
INNER JOIN PUBLIC.ITEM as item ON item.id = shelfitems.item_id
GROUP BY shelf.id;
不过还有一个要求! - 我还希望同一结果集中的项目 ID 和描述。 所以我想要这样的东西:
SELECT
shelf.id,
item.id,
item.description,
MAX(item.price)
FROM
PUBLIC.SHELF as shelf
INNER JOIN PUBLIC.SHELF_ITEMS as shelfitems ON shelf.id = shelfitems.shelf_id
INNER JOIN PUBLIC.ITEM as item ON item.id = shelfitems.item_id
GROUP BY shelf.id;
然而,这导致了一个错误,指出我需要在 GROUP BY 子句中添加 item.id,当我添加它时,我得到了所有行。
好像我缺少一些条件,说明我只想要最贵的 selected。
SELECT
shelf.id,
item.id,
item.description,
item.price
FROM
shelf shelf
INNER JOIN shelf_items shelfitems ON shelf.id = shelfitems.shelf_id
INNER JOIN item item ON item.id = shelfitems.item_id
WHERE
item.price = (
SELECT
MAX(item_inner.price)
FROM
shelf_items shelfitems_inner
INNER JOIN item item_inner ON item_inner.id = shelfitems_inner.item_id
WHERE
shelf.id = shelfitems_inner.shelf_id
)
纯 HQL/JPQL 解决方案返回实体,假设映射正确完成,Shelf
在 多对多 和 Item
:
@SuppressWarnings("unchecked")
public Map<Shelf, Item> getShelvesWithMaxItemPrice(){
Query query = entityManager.createQuery("SELECT sh, it FROM Shelf sh join sh.items it WHERE it.price = "
+ "(SELECT MAX(itInner.price) FROM Item itInner join itInner.shelves shInner WHERE shInner.id = sh.id)");
List<Object[]> queryResults = query.getResultList();
Map<Shelf, Item> results = new LinkedHashMap<>();
for(Object[] row: queryResults) {
results.put((Shelf) row[0], (Item) row[1]);
}
return results;
}
这将生成与 Ashutosh A 的答案相同的 SQL。