내가 원하는 조건은 다음과 같았다. MYSQL 의 WITH ROLLUP함수처럼 합계를 구하되 이 함수를 쓰지 않는 것이였다.

COUNT() 된 값의 SUM() 즉 SUM(COUNT()) 을 구하고 싶었다.

 

예시 쿼리는 다음과 같다.

 

SELECT    
date_format(LEFT(CAST(REQDT AS UNSIGNED),8),'%Y-%m-%d') AS REQDT,
count(SVCE_DOMAIN) COUNTSVCE

FROM BC_HISTORY
        GROUP BY date_format(LEFT(CAST(REQDT AS UNSIGNED),8),'%Y-%m-%d') WITH ROLLUP;

 

 위 쿼리를 쓰면

 

REQDT COUNTSVCE
2020-11-24 3
2020-11-25 28
2020-11-26 414
2020-11-27 208
2020-11-30 115
2020-12-01 29
2020-12-02 156
2020-12-03 237
2020-12-04 52
2020-12-07 54
2020-12-10 22
2020-12-12 1
  1322

위의 표에서  COUNT (SVCE_DOMAIN)의 별칭인 COUNTSVCE

으로 조회한 컬럼의 합이 출력된다.

(실제 합의 숫자는 정확하지 않다 깔끔한 데이터를 위해 null 행을 삭제했기 때문이지만 원리는 같다)

즉 WITH ROLLUP(MYSQL은 WITH 앞에 붙여주어야 한다) 를 쓰면 COUNTSVCE의 누적 합계값을 구할 수 있다.

 

그러나 위 쿼리에서 ROLLUP을 삭제하고 쿼리를 출력하게되면

REQDT COUNTSVCE
2020-11-24 3
2020-11-25 28
2020-11-26 414
2020-11-27 208
2020-11-30 115
2020-12-01 29
2020-12-02 156
2020-12-03 237
2020-12-04 52
2020-12-07 54
2020-12-10 22
2020-12-12 1
   

이와 같은 데이터가 나올 것이다.

 

나는 ROLLUP함수처럼 누적 합계값을 구하는 것이 목적이었다.

즉 이미 SELECT절에서 GROUP BY로 묶인 값의 COUNT 된 값의 SUM을 구하면 되는 것이었다.

그 해결쿼리는 다음과 같다.

 

 

SELECT SUM(count) AS SUMPLE 

FROM (


SELECT
date_format(LEFT(CAST(REQDT AS UNSIGNED),8),'%Y-%m-%d') AS REQDT,
count(SVCE_DOMAIN) as count


FROM BC_HISTORY
        group by date_format(LEFT(CAST(REQDT AS UNSIGNED),8),'%Y-%m-%d')) AS COUNT

 

이렇게 작성하게되면 1322 값 한 열만 출력된다. (위의 ROLLUP을 사용한 값과 같은 값이 도출된다)

즉 단순히 보자면 SUM(COUNTSVCE) 값을 구해준 것이다.

 

이런식으로 뼈대를 잡고 적으면 된다

 

``` 

SELECT SUM(합을 구할 COUNT된 컬럼별칭)

FROM(메인 쿼리) AS 별칭 

```

 

으로 적어주면되는데, 여기서 중요한점은 메인쿼리 안의 

 

1. count(SVCE_DOMAIN) as count 이부분에서 as count처럼 별칭을 정해주어야 한다는 점과

 

2. 서브쿼리 마지막 ...%Y-%m-%d')) AS COUNT 에도 별칭을 달아줘야 에러가 안뜬 다는 것이다.

여기에 별칭 안달아주면 ERRORCODE 1248 발생함

(총 2군데 별칭)

 

간단하지만 막상 짤려고하면 기억이 안나거나 에러가 발생하는 쿼리인것 같다.

너무 간단한 실수이지만 나처럼 잘 모르는 사람은 고생할 것 같아 글을 적어본다.

셋팅은 mybatis을 통한 mysql 연결상태이다. xml 을 이용하여 sql 쿼리문을 json 형태로 보내는 형태이다.

오류는 이렇다.

오류가 발생한 쿼리는 이렇다.

 

<select id="selectpick" parameterType="JSON" resultType="JSON">
SELECT
date_format(LEFT(CAST(REQDT AS UNSIGNED),8),'%Y-%m-%d') AS REQDT,
count(SVCE_DOMAIN) COUNTSVCE,
SVCE_DOMAIN,
REQID,
REQIP
FROM BC_HISTORY
group by date_format(LEFT(CAST(REQDT AS UNSIGNED),8),'%Y-%m-%d')

<where>
<if test="msgid!=null">
AND MSGID = #{msgid}
</if>

<choose>
<when test="log_yyyymmdd_from) and (log_yyyymmdd_to !=null">
<![CDATA[
AND LEFT(CAST(REQDT AS UNSIGNED),8) BETWEEN #{log_yyyymmdd_from} AND #{log_yyyymmdd_to}
]]>
</when>

</when>
</choose>
</where>

 

여기서 난 오류는 

 

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE  LEFT(CAST(REQDT AS UNSIGNED),8) BETWEEN 20201211 AND 20201217 

 

인데 datepicker로 날짜 data를 입력하면 when 절에서 이를 처리하게끔 하고 싶었다. 그러나 date를 입력하면 위와 같은 오류가 생기는데 간단히 해석하자면 sql절이 잘못 작성되었다는 뜻이다.

 

처음에 이유를 몰라서 해당 절이랑 관련된 쿼리문만 보고 있었는데, 마침내 그 이유를 알아냈다. 바로 group by 절의 위치가 잘못 쓰인 것이다. 

select

*from

where

group by 이 순으로 써야한다는 것은 잘 알 고 있었지만 xml에서 쓸려다보니 이를 망각하고 where절 위에 써버린 것이다.

 

(<where></where> 태그가 where절이다.)

select

*from

<where></where>

group by 

이런 순서로 작성했어야 했다 ㅠㅠ 이걸 모르고 몇시간동안 쓸데없는걸 건드렸다 ㅠㅠ 혹시나 나같이 고생하는 사람이 있을까 적어본다 ㅠㅠ

+ Recent posts