line / kotlin-jdsl

Kotlin library that makes it easy to build and execute queries without generated metamodel
https://kotlin-jdsl.gitbook.io/docs/
Apache License 2.0
686 stars 85 forks source link

How to use 'sum' expression with 'case-when' #39

Closed nayasis closed 2 years ago

nayasis commented 2 years ago

I tried to convert below query to Kotlin-jdsl.

SELECT  id,
        SUM( CASE WHEN role IN ('A','B') THEN amount ELSE 0 END ) AS balance
FROM    TEST_TABLE
GROUP BY id
return query.listQuery {
    selectMulti(
        col(TestTable::id),
        sum(case(
          `when`(col(TestTable::role).`in`("A","B")).then(col(TestTable::occurAmount)),
          `else` = literal(0L)
        )),
    )
    from(entity(TestTable::class))
    groupBy(
        col(TestTable::id),
    )
}

But it could not possible because SumSpec might not support below syntax.

  sum(case(
    `when`(col(TestTable::role).`in`("A","B")).then(col(TestTable::occurAmount)),
    `else` = literal(0L)
  )),

Is there way to possible using sum expression with case-when ?

cj848 commented 2 years ago

Currently, when I check, only column is received. In the JPA specification, Expression can be received, so we will fix it and release it again soon.

-- korean 현재 확인해보니 column 만 받게 되어 있습니다. JPA 스펙에서는 Expression 을 받을 수 있으므로 곧 수정해서 릴리즈를 다시 하도록 하겠습니다.

cj848 commented 2 years ago

There is a PR on #41 that fixed the problem you posted. We will release it after the review is complete.

It was also confirmed that the test for the example posted above works normally.

Please refer to the link below.

-- korean 올려주신 문제를 해결한 PR 이 #41 에 있습니다. 리뷰 완료 후에 릴리즈 하도록 하겠습니다.

위에 올려주신 예제에 대한 테스트도 정상 동작하는 것을 확인하였습니다.

아래 링크를 참고해주세요. https://github.com/line/kotlin-jdsl/pull/41/files#diff-f55a48c42db95f90587e2edb9df029fd40819539d55fd463793784058f3d7c0cR165

nayasis commented 2 years ago

Thank you so much. It works well :)

cj848 commented 2 years ago

I'm glad you enjoyed using it. How do you feel about using it? I'm curious because we haven't received feedback from real users yet.

-- korean 잘 사용해주셔서 기쁩니다. 써보시니 어떠신가요? 아직 실제 유저의 피드백을 받지 못해 궁금합니다.

nayasis commented 2 years ago

피드백이 상당히 늦었네요. ^-^

원장 기반 뱅킹시스템을 구현/유지보수 중이고, Native 쿼리를 제법 사용하고 있던 중이었습니다. 거의 모든 Native 쿼리를 본 라이브러리로 모두 대체할 수 있었습니다. QueryDsl 과는 비교할 수 없을 정도로 적용이 간편하고 사용법이 직관적이네요 ! 주변 지인들에게 꼭 써보시라 입소문 많이 내고 있습니다. ^-^

유일하게 해결 보지 못한 Query 패턴 남기고 갑니다. ( Subquery 로 뽑아 IN 조건에 넣어 처리는 했습니다만... Self 조인 자체를 어떻게 쓸 수 있는지 궁금하긴 합니다. ^-^)

SELECT A.* FROM A JOIN ( SELECT id FROM A WHERE .... ) B ON (A.id = B.id)

좋은 라이브러리 만들어 주셔서 감사합니다. 즐거운 주말 되세요 ^-^

cj848 commented 2 years ago

https://stackoverflow.com/a/53394622/3505537

Please refer to the answer. A subquery in the from clause is not allowed in the original Criteria.

Because our library is written through the JPA Criteria API, we cannot create queries that JPA Criteria does not allow.

I am very glad that you are using it well. There was also a reactive version of the release recently. Please use it a lot.

-- korean stackoverflow 답변을 참고해주세요. from 절 안의 subquery 는 원래 Criteria 에서 허용하지 않습니다.

저희 라이브러리가 JPA Criteria API 를 통해서 작성 되었기 때문에 JPA Criteria 가 허용하지 않는 쿼리는 만들 수 없습니다.

잘 사용해주시니 많이 기쁩니다. 최근에 reactive 버전의 릴리즈도 있었습니다. 많은 활용 부탁드립니다.

cj848 commented 2 years ago

Subquery inside the select clause, which is the way you solved it now This can only be done in a where clause or having clause.

-- korean 지금 해결하신 방식인 select 절 내부의 subquery, where 절 혹은 having 절에서만 가능합니다.