问题
We're developing a web application which uses EJB to connect to a database.
In our DB model, we have a mobile devices table, another one with features, and the last one that maps the values of the features with the phone models. models (id_model,...) features (id_feature, ...) model_features (id_model, id_feature, value)
We want to perform a query that gets the models ordered by the number of matching features. It's to say, we pass a list of features to match (i.e. from 1 to 9), and we want all the devices containing 'yes' as the value of at least one of those features, and order them as previously said.
We created an SQL query that makes that job, and it works:
SELECT CONCAT(subquery.numberf*100/9,"%") AS "Features", subquery.idModel AS "ID model"
FROM (select count(*) AS numberf, id_model AS idModel
FROM model_features
WHERE value LIKE '%Yes%' AND id_feature IN(1,2,3,4,5,6,7,8,9)
GROUP BY id_model) subquery
WHERE subquery.numberf > 0
ORDER BY subquery.numberf DESC
Since we're using JPA and therefore we've got to build JPQL querys, it's not possible to include subquerys in the FROM clause, and we're wondering whether we can "pass" the subquery to the WHERE clause is possible and does not affect the performance in a bad way. How can we do?
回答1:
Finally we solved using a native query:
String query = "SELECT ROUND(subquery.numberf*100/" + features + ",0) AS \"matches\", m.id_model AS \"id_model\", m.name AS \"name\", m.brand AS \"brand\", m.url_pict AS \"url_picture\""
+ " FROM (select count(*) AS numberf, id_model AS idModel FROM model_features WHERE value LIKE '%Yes%' "
+ "AND id_feature IN(" + idFeatures + ") GROUP BY id_model) subquery, Models m WHERE subquery.numberf > 0 "
+ "AND subquery.idModel = m.id_model ORDER BY subquery.numberf DESC, m.name";
return em.createNativeQuery(query).getResultList();
来源:https://stackoverflow.com/questions/8807756/jpa-subquery-in-from-clause