[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-3356) Support for subselect (subquery) in from clause
Chris Wilson (JIRA)
noreply at atlassian.com
Wed Nov 17 10:53:14 EST 2010
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3356?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=39138#action_39138 ]
Chris Wilson commented on HHH-3356:
-----------------------------------
Provided that you don't need to JOIN to a subselect, e.g. if you just want to further summarise the results of a query, you can use our SuperSelect custom query (http://rita.logscluster.org/browser/rita/src/org/wfp/rita/db/SuperSelect.java). It has a few dependencies that you can pull out from the RITA source, or just remove.
You can see some examples of its use here: http://rita.logscluster.org/browser/rita/src/org/wfp/rita/datafacade/DashboardDao.java, especially the DashboardQuery() constructor. The main process is:
* Create a criteria query for the inner query (subselect)
* Create a SuperSelect around it
* select() some columns from the inner query in the SuperSelect, e.g. by wrapping InnerQueryExpression, NonGroupedExpression and AggregateFunctionExpression objects around some of the inner query's Criterion objects
* Restrict result set rows with where()
* sort() the outer result set
* list() the SuperSelect to return the projected rows.
The getDispatchesByDateQuery() function uses SuperSelect to build a query like this:
{code:sql}
SELECT
(0 - SUM(ship_ltu_weight * (ship_ltu_qty / line_ltu_qty))) AS dispatch_weight,
(0 - SUM(ship_ltu_volume * (ship_ltu_qty / line_ltu_qty))) AS dispatch_volume,
dispatch_month
FROM
(SELECT
SUM(dispatch.ltu_qty) AS ship_ltu_qty,
line.ltu_qty AS line_ltu_qty,
line.ltu_weight AS ship_ltu_weight,
line.ltu_volume AS ship_ltu_volume,
CAST(CONCAT(LEFT(journey.actual_dispatch_time, 7), "-01") AS DATE) AS dispatch_month
FROM
movement AS dispatch
INNER JOIN location AS origin
ON origin.location_site_id = dispatch.affected_location_site_id
AND origin.id = dispatch.affected_location_id
INNER JOIN site AS origin_site
ON origin_site.id = origin.parent_site_id
INNER JOIN request_line AS line
ON line.request_site_id = dispatch.request_site_id
AND line.id = dispatch.request_line_id
INNER JOIN product
ON product.id = line.product_id
LEFT OUTER JOIN product AS family
ON family.product_idnf = SUBSTR(product.product_idnf, 1, 3)
INNER JOIN request
ON request.request_site_id = line.request_site_id
AND request.id = line.request_id
INNER JOIN project
ON project.id = request.project_id
INNER JOIN country
ON country.id = project.country_id
INNER JOIN site AS request_site
ON request_site.id = request.request_site_id
LEFT OUTER JOIN contact AS sender
ON sender.owner_site_id = request.sender_site_id
AND sender.id = request.sender_contact_id
LEFT OUTER JOIN org AS sender_org
ON sender_org.id = sender.org_id
LEFT OUTER JOIN org_type AS sender_org_type
ON sender_org_type.code = sender_org.org_type_code
INNER JOIN shipment
ON shipment.shipment_site_id = dispatch.shipment_site_id
AND shipment.id = dispatch.shipment_id
INNER JOIN location AS destination
ON destination.location_site_id = shipment.destination_location_site_id
AND destination.id = shipment.destination_location_id
INNER JOIN site AS destination_site
ON destination_site.id = destination.parent_site_id
INNER JOIN journey
ON journey.journey_site_id = shipment.shipment_site_id
AND journey.id = shipment.journey_id
LEFT OUTER JOIN vehicle_category
ON vehicle_category.id = journey.vehicle_category_id
WHERE dispatch.is_deleted = false
AND shipment.is_deleted = false
AND journey.is_deleted = false
AND line.is_deleted = false
AND request.is_deleted = false
AND project.id = $P{Project_ID}
AND origin_site.id = $P{Site_ID}
AND journey.actual_dispatch_time IS NOT NULL
AND journey.actual_dispatch_time > "2000-01-01"
AND dispatch.movement_ledger_code = "S"
AND journey.journey_type_code = "T"
GROUP BY
line.ltu_qty,
line.ltu_weight,
line.ltu_volume,
origin.location_site_id,
origin.id,
shipment.shipment_site_id,
shipment.id,
CAST(CONCAT(LEFT(journey.actual_dispatch_time, 7), "-01") AS DATE)) AS select_0
WHERE (ship_ltu_qty < 0)
GROUP BY
dispatch_month
{code}
It should be quite easy to add support for multiple subselects, and joining them together, to get the kind of query that Arbi Sookazian was asking for. I just haven't needed it yet, so I haven't had a reason to implement it.
> Support for subselect (subquery) in from clause
> -----------------------------------------------
>
> Key: HHH-3356
> URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3356
> Project: Hibernate Core
> Issue Type: New Feature
> Components: query-hql
> Reporter: Geoffrey De Smet
>
> Many databases support subselects in the from clause, for example:
> http://dev.mysql.com/doc/refman/5.0/en/unnamed-views.html
> And it's very handy.
> Native query's are sometimes a working workaround, but have many disadvantages, unlike HQL.
> Btw, I've searched through jira for over 20 minutes and didn't find an issue for this already. If there is one already, please give it a better title or link it to this issue :)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the hibernate-issues
mailing list