【发布时间】:2013-04-07 12:25:53
【问题描述】:
我的 Oracle 数据库中有两个表 product 和 product_image。它们具有从product 到product_image 的一对多关系。因此,这种关系可以在 Hibernate 中映射如下。
产品实体:
@Entity
@Table(name = "PRODUCT", catalog = "", schema = "WAGAFASHIONDB")
public class Product implements java.io.Serializable
{
@OneToMany(mappedBy = "prodId", fetch = FetchType.LAZY)
private Set<ProductImage> productImageSet;
}
@Entity
@Table(name = "PRODUCT_IMAGE", catalog = "", schema = "WAGAFASHIONDB")
public class ProductImage implements java.io.Serializable
{
@ManyToOne(fetch = FetchType.LAZY)
private Product prodId;
}
我需要查询可以从product_image 表中的每组产品中获取具有最大prod_image_id(prduct_image 表的主键)的行列表。
这是我的previous question。这可以通过以下 SQL 完成。
SELECT
pi.prod_image_id,
pi.prod_id, pi.prod_image
FROM
product_image pi
INNER JOIN (
SELECT
MAX(pi.prod_image_id) AS prod_image_id
FROM
product_image pi
GROUP BY
pi.prod_id
) prod_image
ON pi.prod_image_id=prod_image.prod_image_id
该问题的answer 对应于以下正确的 HQL。
SELECT
pi.prodImageId,
pi.prodId
FROM
ProductImage pi
WHERE
pi.prodImageId in (
SELECT
MAX(pis.prodImageId)
FROM
Product p
INNER JOIN
p.productImageSet pis
GROUP BY
p.prodId
)
这完全符合预期的结果。
PROD_IMAGE_ID PROD_ID PROD_IMAGE
662 284 3562298873030291049_Winter.jpg
644 283 7551758088174802741_9392401244_SS_2505.jpg
595 124 298082252715152799_SS_5012.jpg
566 62 7826143854352037374_SS_5004-A.jpg
但我真正需要的是,上面的SQL/HQL检索到的结果集需要与product表和LEFT OUTER JOIN结合起来,这样它就可以从product表中检索每个产品,而不管它们的product_image 表中的图像类似于以下内容。
PROD_IMAGE_ID PROD_ID PROD_IMAGE
662 284 3562298873030291049_Winter.jpg
644 283 7551758088174802741_9392401244_SS_2505.jpg
595 124 298082252715152799_SS_5012.jpg
- 101 -
- 81 -
566 62 7826143854352037374_SS_5004-A.jpg
这可以通过以下本机 SQL 来完成,但使用 HQL 似乎不可能,因为 HQL 只允许在 SELECT 和 WHERE 子句中进行子查询,而在 HQL 中不允许 FROM 子句中的子查询。
SELECT
t.prod_image_id,
p.prod_id,
t.prod_image
FROM
product p
LEFT OUTER JOIN(
SELECT
pi.prod_image_id,
pi.prod_id,
pi.prod_image
FROM
product_image pi
INNER JOIN (
SELECT
MAX(pi.prod_image_id) AS prod_image_id
FROM
product_image pi
GROUP BY
pi.prod_id
) prod_image
ON pi.prod_image_id=prod_image.prod_image_id
)t ON p.prod_id=t.prod_id ORDER BY p.prod_id DESC;
我的 Google 搜索显示,这对于单个 HQL 语句是不可行的。这对 HQL 有可能吗?请确认我。
【问题讨论】:
-
使用窗口(又称分析)函数将比使用子选择更有效。
-
@a_horse_with_no_name :根据this 的回答,Hibernate 中不允许使用窗口函数。 HQL 不支持窗口函数。
-
啊,ORM 工具的“乐趣”。这简直太愚蠢了,我知道我为什么不喜欢 ORM
标签: oracle hibernate oracle10g hql greatest-n-per-group