본문 바로가기

Spring/Querydsl

Querydsl- 집합

@Test
public void aggregation() {
    /*
     * JPQL
     * select
     *      Count(m),
     *      Sum(m.age),
     *      Avg(m.age),
     *      Max(m.age),
     *      Min(m.age)
     * from Member m
     *
     */

    // Tuple: 다양한 데이터 셋을 저장 가능
    Tuple tuple = queryFactory
            .select(
                    member.count(),
                    member.age.sum(),
                    member.age.avg(),
                    member.age.max(),
                    member.age.min()
            )
            .from(member)
            .fetchOne();

    // Tuple의 데이터를 get() 메서드를 이용해서 조회가능
    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);
}

 한번에 다양한 데이터가 들어있는 집합으로 조회를 하게되면 해당 형은 Tuple 형으로 반환이된다. Tuple에는 다양한 데이터 셋이 저장된다. Tuple에 저장된 형은 get 메소드를 사용하여 조회가 가능하다. get의 파라미터는 저장할 때 사용했던 이름 ( ex) member.count( ) )을 사용한다.

 

group by

/**
 * 팀의 이름과 각 팀의 평균 연령 구하기
 */
@Test
public void group() throws Exception{
	/* 
     * JPQL
     *
     * List<Object[]> resultList = em.createQuery(
     *        "SELECT t.name, AVG(m.age) FROM Member m " +
     *                "JOIN m.team t " +
     *               "GROUP BY t.name", Object[].class)
     *        .getResultList();
     *
     * assertThat((String) resultList.get(0)[0]).isEqualTo("teamA");
     * assertThat((double) resultList.get(0)[1]).isEqualTo(15);
	 *
     * assertThat((String) resultList.get(1)[0]).isEqualTo("teamB");
     * assertThat((double) resultList.get(1)[1]).isEqualTo(35);
     * 
     */

    List<Tuple> result = queryFactory
            .select(team.name, member.age.avg())
            .from(member)
            .join(member.team, team)
            .groupBy(team.name)  // member 엔티티를 team.name으로 그룹화하라! => member 엔티티들중 team.name이 일치하는 것들을 묶어줘라
            .fetch();

    Tuple teamA = result.get(0); // team.name이 "teamA"로 그룹화된 튜플
    Tuple teamB = result.get(1); // team.name이 "teamB"로 그룹화된 튜플

    assertThat(teamA.get(team.name)).isEqualTo("teamA");
    assertThat(teamA.get(member.age.avg())).isEqualTo(15); //10, 20

    assertThat(teamB.get(team.name)).isEqualTo("teamB");
    assertThat(teamB.get(member.age.avg())).isEqualTo(35); //30, 40
}

 group by는 특정 column을 기준으로 레코드들을 그룹화하는데 사용한다. 예를 들어서, 위의 코드는 Member 엔티티를 조회하되, 이를 조인된 Team의 name 필드로 그룹화한다.

 따라서 member들 중에서도 동일한 Team의 name을 가지고 있는 엔티티들끼리 묶여서(그룹화되어) 조회된다. 현재 teamA와 teamB가 존재하여 튜플은 두개의 그룹으로 묶이게 된다.

'Spring > Querydsl' 카테고리의 다른 글

Querydsl- 프로젝션  (0) 2023.08.04
Querydsl- 조인  (0) 2023.07.27
Querydsl- 정렬과 페이징  (0) 2023.07.25
Querydsl- Q 인스턴스  (0) 2023.07.22
Querydsl- Jpql과 Querydsl 비교  (0) 2023.07.22