강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của wiz92436614
wiz92436614

câu hỏi đã được viết

Trong thực tế! Truy vấn

특정 필드의 그룹별 최댓값 조회와 where절에 대한 List 사용 방법

Viết

·

1.3K

0

안녕하세요. 강의를 들으면서 프로젝트를 진행하고 있다가 막히는 부분이 있어서 질문드립니다.

두서 없는 질문이어서 먼저 죄송합니다.

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안에 있는지 판단하는게 지원이 안되는지 궁굼하고 이런 경우에는 어떻게 해결해야 하는지 궁금합니다.

 
JPAjava

Câu trả lời 2

0

coding님의 프로필 이미지
coding
Người đặt câu hỏi

친절하게 답변해주셔서 감사합니다! 그런데 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에서는 어떻게 해야하는 잘 모르겠습니다.....ㅠ

yh님의 프로필 이미지
yh
Người chia sẻ kiến thức

안녕하세요. coding님

이 부분은 저도 잘 모르겠네요.

우선 SQL로 문제를 해결하시는 것이 좋을 것 같아요.

혹시 아시는 분 있으면 답변 부탁드려요.

0

yh님의 프로필 이미지
yh
Người chia sẻ kiến thức

안녕하세요. 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(..) 문법으로 실행해보시겠어요? 만약 이 방법이 안된다면 저도 잘 모르겠습니다. 혹시 아시는 분 있으면 답변 부탁드려요.

감사합니다.

 

StringTemplate jsonExtractValue = Expressions.stringTemplate("JSON_EXTRACT({0}, '$[*]')", entity.category);

...
.where(jsonExtractValue.contains(entity.category))

 

2. 번 문제에 대해 저도 같은 경험이 있어서 제 해결방안에 대해 공유드립니다.

Hình ảnh hồ sơ của wiz92436614
wiz92436614

câu hỏi đã được viết

Đặt câu hỏi