Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

서브쿼리, SubQuery 본문

인프런/[인프런] QueryDsl

서브쿼리, SubQuery

Seung__ 2021. 9. 2. 23:51

1. 서브쿼리


2. 예제1 : 나이가 가장 많은 회원 조회


    /**
     * 나이가 가장 많은 회원 조회
     */
    @Test
    public void subQuery(){

        //서브쿼리는 바깥에 있는 alias랑 겹치면 안됨.
        //QMember새로 만들어줘야함.
        QMember memberSub = new QMember("memberSub");

        List<Member> result = queryFactory
                .selectFrom(member)
                .where(member.age.eq(
                        JPAExpressions
                                .select(memberSub.age.max())
                                .from(memberSub)
                ))
                .fetch();

        assertThat(result).extracting("age").containsExactly(40);
    }
     select
        member1 
    from
        Member member1 
    where
        member1.age = (
            select
                max(memberSub.age) 
            from
                Member memberSub
        )

 

3. 나이가 평균 이상인 회원, goe


    /**
     * 나이가 평균 이상인 회원 조회
     */
    @Test
    public void subQueryGoe(){

        //서브쿼리는 바깥에 있는 alias랑 겹치면 안됨.
        //QMember새로 만들어줘야함.
        QMember memberSub = new QMember("memberSub");

        List<Member> result = queryFactory
                .selectFrom(member)
                .where(member.age.goe(
                        JPAExpressions
                                .select(memberSub.age.avg())
                                .from(memberSub)
                ))
                .fetch();

        assertThat(result).extracting("age").containsExactly(30,40);
    }

 

4. in절 사용


    @Test
    public void subQueryIn(){
        
        QMember memberSub = new QMember("memberSub");

        List<Member> result = queryFactory
                .selectFrom(member)
                .where(member.age.in(
                        JPAExpressions
                                .select(memberSub.age)
                                .from(memberSub)
                                .where(memberSub.age.gt(10))
                ))
                .fetch();

        assertThat(result).extracting("age").containsExactly(20,30,40);
    }

 

5. select에  in 사용


    @Test
    public void selectSubQuery(){

        QMember memberSub = new QMember("memberSub");

        List<Tuple> result = queryFactory
                .select(member.username,
                        JPAExpressions
                                .select(memberSub.age.avg())
                                .from(memberSub)
                ).from(member)
                .fetch();

        for (Tuple tuple : result) {
            System.out.println("tuple = " + tuple);
        }
    }
    select
        member1.username,
        (select
            avg(memberSub.age) 
        from
            Member memberSub) 
    from
        Member member1
tuple = [member1, 25.0]
tuple = [member2, 25.0]
tuple = [member3, 25.0]
tuple = [member4, 25.0]

 

6. from절의 서브쿼리 한계


  • JPA JPQL 서브쿼리의 한계점으로 from 절의 서브쿼리(인라인 뷰)는 지원하지 않는다. 
  • 당연히 Querydsl도 지원하지 않는다. 
  • 하이버네이트 구현체를 사용하면 select 절의 서브쿼리는 지원한다. 
  • Querydsl도하이버네이트 구현체를 사용하면 select 절의 서브쿼리를 지원한다.

 

7. from 절의 서브쿼리 한계점 해결 방안


  • 서브쿼리를 join으로 변경한다. (가능한 상황도 있고, 불가능한 상황도 있다.)
  • 애플리케이션에서 쿼리를 2번 분리해서 실행한다.
  • nativeSQL을 사용한다.

 

8.GitHub : 210902 SubQuery


 

GitHub - bsh6463/Querydsl

Contribute to bsh6463/Querydsl development by creating an account on GitHub.

github.com

 

'인프런 > [인프런] QueryDsl' 카테고리의 다른 글

상수, 문자 더하기  (0) 2021.09.03
Case 문  (0) 2021.09.02
Join  (0) 2021.09.02
집합  (0) 2021.09.01
페이징  (0) 2021.09.01
Comments