Posts [자바 ORM 표준 JPA 프로그래밍-기본편] 서브 쿼리
Post
Cancel

[자바 ORM 표준 JPA 프로그래밍-기본편] 서브 쿼리

본 포스팅은 인프러의 JPA 기본편을 수강하고 정리하는 내용입니다.


서브 쿼리

  • 나이가 평균보다 많은 회원
1
2
select m from Member m
where m.age > (select avg(m2.age) from Member m2)

위에 있는 m 대신 서브 쿼리에서 새로운 m2를 사용하면 성능이 더 잘 나온다.

  • 한 건이라도 주문한 고객
1
2
select m from Member m
where (select count(o) from Order o where m = o.member) > 0

위에 있는 m 을 서브 쿼리에서 사용하면 성능이 잘 안 나온다.

서브 쿼리 지원 함수

  • [NOT] EXISTS (subquery): 서브쿼리에 결과가 존재하면 참
    • {ALL | ANY | SOME} (subquery)
    • ALL 모두 만족하면 참
    • ANY, SOME: 같은 의미, 조건을 하나라도 만족하면 참
  • [NOT] IN (subquery): 서브쿼리의 결과 중 하나라도 같은 것이 있으면 참

서브 쿼리 - 예제

  • 팀A 소속인 회원
1
2
select m from Member m
where exists (select t from m.team t where t.name = ‘팀A')
  • 전체 상품 각각의 재고보다 주문량이 많은 주문들
1
2
select o from Order o
where o.orderAmount > ALL (select p.stockAmount from Product p)
  • 어떤 팀이든 팀에 소속된 회원
1
2
select m from Member m
where m.team = ANY (select t from Team t)

JPA 서브 쿼리 한계(중요)

  • JPA 표준스펙에선 WHERE, HAVING 절에서만 서브 쿼리 사용 가능
  • SELECT 절도 가능(하이버네이트에서 지원)
    1
    2
    3
    
    String query = "select (select avg(m1.age) from Member m1) as avgAge from Member m, Team t where m.username = t.name";
    List<Member> result = em.createQuery(query, Member.class)
            .getResultList();
    
  • FROM 절의 서브 쿼리는 현재 JPQL에서 불가능
    • 조인으로 풀 수 있으면 풀어서 해결
    • 조인으로도 못 풀면 포기해야함 (한계)
    • 정안되면 네이티브 쿼리를 쓰거나 애플리케이션에서 조작하여 쿼리를 두 번 날리도록 한다.
This post is licensed under CC BY 4.0 by the author.

[자바 ORM 표준 JPA 프로그래밍-기본편] 조인

[자바 ORM 표준 JPA 프로그래밍-기본편] JPQL 타입 표현과 기타식