2016-12-02 2 views
12

J'ai une table sql A avec les noms de colonnesSous-Select Dans les critères de mise en veille prolongée

name, id1, id2, val1 

et une table B avec les noms de colonnes

id1, id2, key1, key2 

ce qui est ma requête SQL

SELECT 
    v1.id1, 
    v1.id2 
FROM (
     SELECT 
     A.id1, 
     A.id2, 
     min(val1) AS x 
     FROM A 
     JOIN B ON A.id1 = B.id1 AND A.id2 = B.id2 
     GROUP BY A.id1, A.id2 
    ) AS v1 
WHERE v1.x > 10 

en utilisant le DetachedCriteria j'ai pu former la sous-requête

DetachedCriteria subCriteria = DetachedCriteria.forClass(A_model.class); 
subCriteria.createAlias("b", "b_model"); 
subCriteria.setProjection(Projections.projectionList() 
          .add(Projections.groupProperty("id1")) 
.add(Projections.groupProperty("id2")) 
.add(Projections.min("val1"),"x"); 

mais j'ai du mal à créer la requête externe.

toute suggestion comment puis-je créer les critères pour le SQL ci-dessus?

Merci d'avance.

+1

Les requêtes de critères fonctionnent sur des entités et non sur des tables. Nous n'avons aucune idée de ce à quoi ressemblent les entités. –

+1

@JBNizet J'ai fourni les colonnes pour les tables et sql que je veux. avez-vous besoin de plus d'informations en dehors de cela. pouvez-vous suggérer une solution générique pour la sous-sélection par critères (n'hésitez pas à supposer une structure d'entité correspondante) – sumit

Répondre

1

La sélection de Select n'est supportée ni par HQL ni par l'objet Criteria. La solution ici serait Named Query.

@NamedNativeQueries({ 
    @NamedNativeQuery(
    name = "findV1", 
    query = "SELECT 
       v1.id1, 
       v1.id2 
      FROM (
        SELECT 
        A.id1, 
        A.id2, 
        min(val1) AS x 
        FROM A 
        JOIN B ON A.id1 = B.id1 AND A.id2 = B.id2 
        GROUP BY A.id1, A.id2 
       ) AS v1 
      WHERE v1.x > 10" 
    ) 
}) 
2

Envisager la création d'une vue pour les données dont vous avez besoin:

create view A_B_BY_ID1_AND_ID2 as 
select A.id1, 
     A.id2, 
     min(val1) as x 
from A 
join B on A.id1 = B.id1 and A.id2 = B.id2 
group by A.id1, 
     A.id2 

Ensuite, créez un DTO pour représenter ces données:

@Entity(table="A_B_BY_ID1_AND_ID2") 
@Data //are you on board with lombok? 
public class ABById1AndId2 { 
    @Column 
    private int x; 
    @Column 
    private int id1; 
    @Column 
    private int id2; 
} 

accéder ensuite comme toute autre chose:

session.createCriteria(ABById1AndId2.class).add(Restrictions.gt("x", 10)).list(); 
3

Sous-sélections en La clause from n'est pas prise en charge par Hibernate pour le moment. Cependant, votre requête peut être réécrite sous une forme plus simple et plus efficace en utilisant la clause HAVING:

SELECT A.id1, A.id2, 
FROM A JOIN B ON A.id1 = B.id1 AND A.id2 = B.id2 
GROUP BY A.id1, A.id2 
HAVING min(val1) > 10 

La requête ci-dessus peut être facilement porté à HQL ou critères.