일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Diary 해우소
- 객체지향 언어
- 스파르타내일배움캠프TIL
- 클래스
- 감사기록
- #스파르타내일배움캠프
- KPT
- diary
- Github_token
- 성장기록
- 포맷은 최후의 보루
- Java
- Token
- 변수의 다양성
- 회고록
- Java의 이점
- TiL_1st_0419
- #스파르타내일배움캠프TIL
- 인스턴스
- 내일배움캠프
- static
- 메서드
- Git
- GitHub
- 스파르타내일배움캠프
- 스레드
- JVM
- 해우소
- #내일배움캠프
- 생성자
- Today
- Total
몬그로이
SubQuery, JPAExpressions 본문
사용하는 때
1. 복잡한 조건을 사용해야 할 때
메인 쿼리에서 사용하기 어려운 복잡한 조건을 처리하기 위해
예) 특정 조건에 맞는 데이터만 필터링해야 할 때
2. 집계 함수와 함께 사용할 때
집계된 데이터를 메인 쿼리에서 다시 처리하기 위해
예) 특정 그룹의 최대값, 최소값, 평균값 등을 구하고 이를 메인 쿼리에서 사용
3. 존재 유무 확인
특정 조건에 맞는 데이터가 존재하는지 확인할 때
예) 특정 조건을 만족하는 레코드가 존재하는 경우에만 데이터를 조회할 때
4. 순위 및 순번 지정
특정 순위나 순번을 지정하기 위해
예) 각 그룹 내에서 순위를 매기거나, 순번을 지정할 때
예시
1. 복잡한 조건을 처리하기 위한 서브쿼리
가장 최근 주문 날짜를 가진 고객을 조회하는 경우
SELECT * FROM Customer c
WHERE c.order_date = (SELECT MAX(order_date) FROM Orders o WHERE o.customer_id = c.id);
2. 집계 함수와 함께 사용
각 부서의 평균 급여보다 높은 급여를 받는 직원 조회
SELECT * FROM Employee e
WHERE e.salary > (SELECT AVG(salary) FROM Employee WHERE department_id = e.department_id);
3. 존재 유무 확인
주문이 있는 고객 조회
SELECT * FROM Customer c
WHERE EXISTS (SELECT 1 FROM Orders o WHERE o.customer_id = c.id);
4. 순위 및 순번 지정
각 부서에서 급여 순위가 높은 직원 조회
SELECT * FROM Employee e1
WHERE salary > (
SELECT AVG(salary)
FROM Employee e2
WHERE e1.department_id = e2.department_id
);
QueryDSL에서의 서브쿼리 사용 예시
1. 복잡한 조건을 처리하기 위한 서브쿼리 - 가장 큰 나이를 가진 멤버 찾기
QMember memberSub = new QMember("memberSub");
List<Member> result = queryFactory
.selectFrom(member)
.where(member.age.eq(
JPAExpressions
.select(memberSub.age.max())
.from(memberSub)
))
.fetch();
2. 집계 함수와 함께 사용
QMember memberSub = new QMember("memberSub");
List<Member> result = queryFactory
.selectFrom(member)
.where(member.salary.gt(
JPAExpressions
.select(memberSub.salary.avg())
.from(memberSub)
.where(memberSub.department.id.eq(member.department.id))
))
.fetch();
3. 존재 유무 확인
QOrder order = QOrder.order;
List<Customer> result = queryFactory
.selectFrom(customer)
.where(
JPAExpressions
.selectOne()
.from(order)
.where(order.customer.id.eq(customer.id))
.exists()
)
.fetch();
4. 순위 및 순번 지정
QMember memberSub = new QMember("memberSub");
List<Member> result = queryFactory
.selectFrom(member)
.where(member.salary.gt(
JPAExpressions
.select(memberSub.salary.avg())
.from(memberSub)
.where(memberSub.department.id.eq(member.department.id))
))
.fetch();
JPAExpressions: 서브쿼리를 작성하는 데 사용되는 도구
서브 쿼리 주요 메서드
- select: 서브쿼리를 시작하는 데 사용됩니다.
- selectOne: SELECT 1과 같이 단일 상수를 반환하는 서브쿼리를 작성합니다.
- selectFrom: 특정 테이블 또는 엔티티를 대상으로 서브쿼리를 작성합니다.
- exists: 존재 여부를 확인하는 서브쿼리를 작성합니다.
- notExists: 존재하지 않음을 확인하는 서브쿼리를 작성합니다.
JPA JPQL 서브쿼리의 한계
from 절에서 사용 불가
- Hibernate 구현체를 사용하면 Hibernate 에서 지원해주기 때문에 select 절에서 사용이 가능한 것
해결 방안
- 서브쿼리를 join 으로 변경(불가능할 때도 있으나 가능한 경우가 많음)
- 애플리케이션에서 쿼리를 2번 분리해서 실행한다
- 정 안 될때는 nativeSQL 사용할 것
'Organizing Docs > Java Docs' 카테고리의 다른 글
자바의 정석 8. 예외처리 (1) | 2024.07.05 |
---|---|
Coding 01 (0) | 2024.07.04 |
JPQL - 복잡한 쿼리를 수동으로 작성하고 실행하는 방법 (0) | 2024.06.30 |
ORM (0) | 2024.06.28 |
Spring Data JPA (0) | 2024.06.28 |