집합 함수

@BeforeEach
void setUp() {
    queryFactory = new JPAQueryFactory(em);

    Team teamA = new Team("teamA");
    Team teamB = new Team("teamB");
    em.persist(teamA);
    em.persist(teamB);

    Member member1 = new Member("member1", 10, teamA);
    Member member2 = new Member("member2", 20, teamA);
    Member member3 = new Member("member3", 30, teamB);
    Member member4 = new Member("member4", 40, teamB);
    em.persist(member1);
    em.persist(member2);
    em.persist(member3);
    em.persist(member4);
}

@Test
public void aggregation() throws Exception {
    List<Tuple> result = queryFactory
				    //...2
            .select(member.count(), //회원수
                    member.age.sum(), //나이 합
                    member.age.avg(), //평균 나이
                    member.age.max(), //최대 나이
                    member.age.min()) //최소 나이
            .from(member)
            .fetch();
    Tuple tuple = result.get(0);
    assertThat(tuple.get(member.count())).isEqualTo(4);
    assertThat(tuple.get(member.age.sum())).isEqualTo(100);
    assertThat(tuple.get(member.age.avg())).isEqualTo(25);
    assertThat(tuple.get(member.age.max())).isEqualTo(40);
    assertThat(tuple.get(member.age.min())).isEqualTo(10);
}
  1. Tuple

    자세히

  2. JPQL이 제공하는 모든 집합 함수를 제공합니다.

GroupBy 사용

팀의 이름과 각 팀의 평균 연령을 구하는 GroupBy 테스트 코드를 작성해봅시다.

import static study.querydsl.entity.QTeam.team;

@BeforeEach
void setUp() {
    queryFactory = new JPAQueryFactory(em);

    Team teamA = new Team("teamA");
    Team teamB = new Team("teamB");
    em.persist(teamA);
    em.persist(teamB);

    Member member1 = new Member("member1", 10, teamA);
    Member member2 = new Member("member2", 20, teamA);
    Member member3 = new Member("member3", 30, teamB);
    Member member4 = new Member("member4", 40, teamB);
    em.persist(member1);
    em.persist(member2);
    em.persist(member3);
    em.persist(member4);
}

@Test
public void group() {
    List<Tuple> result = queryFactory
            .select(team.name, member.age.avg())
            .from(member)
            .join(member.team, team)
            .groupBy(team.name)
            .fetch();
    Tuple teamA = result.get(0);
    Tuple teamB = result.get(1);
    assertThat(teamA.get(team.name)).isEqualTo("teamA");
    assertThat(teamA.get(member.age.avg())).isEqualTo(15);
    assertThat(teamB.get(team.name)).isEqualTo("teamB");
    assertThat(teamB.get(member.age.avg())).isEqualTo(35);
}
  1. join()

테스트 코드를 실행해서 쿼리를 봅시다.

Untitled

JPQL 을 보면 member와 team 을 내부조인하고 team.name 으로 group by 를 했습니다.

SQL 도 동일하죠.

Having 사용

마찬가지로 having 조건도 넣을 수 있습니다.

예를 들어, item 엔티티가 있고 가격에 대한 데이터를 가지고 있을 때 1000원이 넘는 item 만 뽑고 싶다면 아래처럼 코드를 작성할 수 있겠죠.