com.querydsl.jpa.JPAExpressions 사용

/**
 * 나이가 가장 많은 회원 조회
 */
@Test
public void subQuery() {
	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);
}
/**
 * 나이가 평균 이상인 회원 조회
 */
@Test
public void subQueryGoe() {
	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);
}

in도 써보자.

/**
 * 나이가 10 보다 많은 회원 조회
 */
@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);
}

Select절에서도 된다!!

@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);
	}
}

from 절의 서브쿼리 한계

JPA JPQL 서브쿼리의 한계점으로 from 절의 서브쿼리 (인라인 뷰)는 지원하지 않는다.

그렇기 때문에 당연히 Querydsl도 지원이 안된다. select 절의 서브쿼리는 하이버네이트 구현체에서 지원하는 것이다.