특정 필드의 그룹별 최댓값 조회와 where절에 대한 List 사용 방법
1333
작성한 질문수 15
안녕하세요. 강의를 들으면서 프로젝트를 진행하고 있다가 막히는 부분이 있어서 질문드립니다.
두서 없는 질문이어서 먼저 죄송합니다.
1. 첫번째는 https://www.inflearn.com/questions/14139 와 비슷한 질문입니다.
지금 하고 있는 프로젝트에서 상품에 대한 테이블은 다음과 같습니다.
id price discountPrice shopId
1 10000 9000 1
2 12000 10000 1
3 8000 7500 1
4 10000 9900 2
이때 discountPrice와 price로 할인율을 계산하였는데요.
shopId별로 가장 할인율이 높은 것을 1개 뽑고 그 뽑은 것들 중에서 할인율이 높은 순으로 10개를 뽑고 싶습니다.
할인율은 (price-discountPrice)/price * 100 으로 계산하였습니다.
queryDSL에서는 from에 대한 서브쿼리를 지원하지 않아 위의 질문처럼 2개 쿼리를 쓰거나 네이티브 쿼리를 쓰려고 하는데요.
이 상황에서 2개 쿼리를 쓴다는게 어떻게 써야하는지 잘 모르겠어서 질문 드립니다.
또 다음
https://helloino.tistory.com/120
https://pepperoni.netlify.app/mysql%EC%97%90%EC%84%9C%20%EA%B7%B8%EB%A3%B9%EB%B3%84%20%EC%B5%9C%EC%8B%A0%20%EB%8D%B0%EC%9D%B4%ED%84%B0%20%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0/
두 개의 자료를 참조하여 다음과 같이 만들었습니다. 할인율을 직접 보려고 rate라는 걸 추가했는데 0으로 나오네요...
왜 안되는지도 궁금합니다
QProduct p1 = new QProduct("p1");
QProduct p2 = new QProduct("p2");
return queryFactory.select(Projections.fields(ProductTmp.class,
shop.id.as("shopId"),
shop.name.as("shopName"),
p1.id,
p1.name,
p1.price,
p1.discountedPrice,
p1.price.subtract(p1.discountedPrice).divide(p1.price).multiply(100L).as("rate"),
p1.image))
.from(p1)
.innerJoin(p1.shop, shop)
.leftJoin(p2)
.on(p1.shop.id.eq(p2.shop.id)
.and(p1.price.subtract(p1.discountedPrice).mod(p1.price).multiply(100L)
.lt(p2.price.subtract(p2.discountedPrice).mod(p2.price).multiply(100L))))
.where(p2.id.isNull())
.orderBy(p1.price.subtract(p1.discountedPrice).mod(p1.price).multiply(100L).desc())
.limit(10)
.fetch();
2. 하고 있는 프로젝트에서 Shop 이란 Entity 안에는 List<String>category가 있습니다.
그런데 DB로 들어갈때는 해당 List의 요소들을 꺼내서 ,(콤마)로 이어서 하나의 String으로 만들어 DB에 넣어주고
DB에서 꺼낼때는 ,(콤마) 기준으로 나누어서 List<String>으로 꺼내줍니다.
이때 저는 입력으로 들어오는 String category가 shop의 category 안에 있는지 판단하고 이것을 where 절에 넣고 싶어서 다음을 구현했습니다.
public BooleanExpression eqCategory(String category) {
return hasText(category) ? shop.category.contains(category) : null;
}
.where(eqCategory(category))
그런데 해당 에러가 뜨면서 되지 않습니다.
java.lang.NullPointerException: Cannot invoke "org.hibernate.persister.collection.QueryableCollection.getElementPersister()" because "queryableCollection" is null
shop.category.getType()은 interface java.util.List가 나오고 shop.category.getClass()는 class com.querydsl.core.types.dsl.ListPath가 나왔습니다.
queryDSL에서는 List안에 있는지 판단하는게 지원이 안되는지 궁굼하고 이런 경우에는 어떻게 해결해야 하는지 궁금합니다.
답변 2
0
친절하게 답변해주셔서 감사합니다! 그런데 1번에서 제 상황에서 shopId 별로 가장 할인율이 높은 걸 뽑아내는 방법을 모르겠습니다ㅠ
이론으로는 product 1과 shop과 product2와 shop을 inner join 한 뒤, product2를 product1에다가 product1.shop.id == product2.shop.id and product1.할인율 < product2.할인율 조건으로 left join 을 하고, 거기서 product2.isNull()을 구하면 될 것 같은데 queryDSL에서는 어떻게 해야하는 잘 모르겠습니다.....ㅠ
0
안녕하세요. coding님
1. shopId별로 가장 할인율이 높은 것을 1개 뽑고 그 뽑은 것들 중에서 할인율이 높은 순으로 10개를 뽑고 싶습니다.
-> 여기서 쿼리를 2개로 쪼갠다는 뜻은
1. shopId별로 가장 할인율이 높은 것을 1개 뽑고 -> 이 부분만 쿼리로 실행해서 상품 id를 뽑아냅니다.
2. 이렇게 뽑은 상품 id를 where in 쿼리를 사용해서 할인율이 높은 순으로 10개를 뽑으시면 됩니다.
그런데 비즈니스 상황에 따라서 이렇게 할 수 없을 수도 있습니다. 이 경우 네이티브 쿼리나 JdbcTemplate을 사용하시면 됩니다.
2. 하고 있는 프로젝트에서 Shop 이란 Entity 안에는 List<String>category가 있습니다. 그런데 DB로 들어갈때는 해당 List의 요소들을 꺼내서 ,(콤마)로 이어서 하나의 String으로 만들어 DB에 넣어주고 DB에서 꺼낼때는 ,(콤마) 기준으로 나누어서 List<String>으로 꺼내줍니다.
-> 저도 해보지 않아서 정확히는 모르겠지만, lists.any().stringValue().contain(..) 문법으로 실행해보시겠어요? 만약 이 방법이 안된다면 저도 잘 모르겠습니다. 혹시 아시는 분 있으면 답변 부탁드려요.
감사합니다.
0
StringTemplate jsonExtractValue = Expressions.stringTemplate("JSON_EXTRACT({0}, '$[*]')", entity.category);
...
.where(jsonExtractValue.contains(entity.category))
2. 번 문제에 대해 저도 같은 경험이 있어서 제 해결방안에 대해 공유드립니다.
SpringBoot 4.X에서의 Querydsl 설정
0
91
2
querydsl 오픈소스에 대한 질문
0
72
1
예제에서의 카운트 쿼리에서 join문과 where문은 필요없지 않나요?
0
109
1
Querydsl 6.X버전에 대해서 어떻게 생각하시나요?
0
317
2
여러 테이블 조인하여 통계치를 구하고자 할 때 어떤 방법이 더 효율적일까요
1
70
1
fetchResults()는 더이상 권장되지 않는다는데 맞나요?
0
160
1
querydsl sum() 메서드 없어요.
0
159
2
build 디렉터리 생성
0
138
2
자바 ORM 표준 JPA 프로그래밍 - 기본편 듣고 바로 학습해도 괜찮을까요?
0
114
2
현재 Querydsl에서 from절 서브쿼리를 지원하나요?
0
92
1
오타 제보 드립니다.
0
72
2
벌크 연산과 flush, clear
0
76
1
Run As Intellij 로 변경시 Q타입 import 불가
0
88
1
QHello import하기 문제 발생
0
147
2
등록된 함수 보는법(H2Dialect) 질문
0
68
2
5.0부터 Querydsl은 향후 fetchCount() , fetchResult() 를 지원하지 않기로 결정했다고 하는데 이에 맞는 강의
1
197
2
[환경설정 PDF 부트 3.0이후 설명 질문] build.gradle에 compileQuerydsl을 정의하지 않은 상태에서 Gradle->Tasks->other->compileQuerydsl을 클릭하라고 하는 이유가 무엇인가요??
1
201
1
querydsl 설정 문제
0
222
2
quey dsl 설정부분
0
158
2
count 쿼리 관련 질문입니다!
0
75
1
stringtemplate를 이용하여 where절 검색 방법 질문 드립니다.
0
89
1
답변부탁드리겠습니다.
0
90
2
(OrderSpecifier)관련 내용 어디있을가요
0
66
1
중급문법 벌크연산에서
0
83
2





