본문 바로가기
일지

[mysql] 정렬 후 그룹화

by 참새는 짹짹 2021. 2. 2.

며칠 전

db 테이블에서 컬럼을 뽑아내

JSON 형식으로 만들어 낼 일이 있어 쿼리를 짜는데

정렬이 잘 안돼서 애 먹은 적이 있다

하고자 했던 동작은

위의 2개의 테이블을 가지고

목표

이런식으로

뽑아내는 게 목표였다

💡
그리고 ORDER_RANK가 있기에 'ITEM_LIST' 에도 ORDER_RANK 순으로 쌓이게 하려 했다

조인 & 그룹화 하기


우선 두 테이블을 가지고 ORDER_SEQ로 그룹화 해야 하므로

기본적으로

SELECT
*
FROM ORDER_TABLE o
JOIN ITEM_TABLE i ON o.ITEM_SEQ = i.ITEM_SEQ
GROUP BY o.ORDER_SEQ;

  • ITEM_SEQ 을 기준으로 조인
  • ORDER_SEQ 을 기준으로 그룹화

하도록 쿼리를 만들었다

JSON 형식으로 만들기


구글링을 통해

그룹 함수(?) 'GROUP_CONCAT' 을 사용하여

만들 수 있음을 확인했다

SELECT
o.ORDER_SEQ,
GROUP_CONCAT(
CONCAT(
'{ITEM_TITLE:"', i.ITEM_TITLE,
'", ORDER_INFO:"',o.ORDER_INFO,
'", ORDER_RANK:"', o.ORDER_RANK, '"}')
) ITEM_LIST
FROM ORDER_TABLE o
JOIN ITEM_TABLE i ON o.ITEM_SEQ = i.ITEM_SEQ
GROUP BY o.ORDER_SEQ;

정렬하기


이제 ORDER_RANK 순으로 정렬을 해야하는데

SELECT
o.ORDER_SEQ,
GROUP_CONCAT(
CONCAT(
'{ITEM_TITLE:"', i.ITEM_TITLE,
'", ORDER_INFO:"',o.ORDER_INFO,
'", ORDER_RANK:"', o.ORDER_RANK, '"}')
) ITEM_LIST
FROM ORDER_TABLE o
JOIN ITEM_TABLE i ON o.ITEM_SEQ = i.ITEM_SEQ
GROUP BY o.ORDER_SEQ
ORDER BY o.ORDER_RANK;

이런식으로 하면 그룹화를 이미 진행하고

정렬을 하기 때문에

원하던 동작과 그 의미가 달라지게 된다

그래서

쿼리문은 좀 지저분해지만

정렬 후 그룹화를 하려면

SELECT
o.ORDER_SEQ,
GROUP_CONCAT(
CONCAT(
'{ITEM_TITLE:"', i.ITEM_TITLE,
'", ORDER_INFO:"',o.ORDER_INFO,
'", ORDER_RANK:"', o.ORDER_RANK, '"}')
) ITEM_LIST
FROM (
		SELECT * FROM ORDER_TABLE
    ORDER BY ORDER_RANK
) o
JOIN ITEM_TABLE i ON o.ITEM_SEQ = i.ITEM_SEQ
GROUP BY o.ORDER_SEQ;

위처럼

이중 쿼리를 작성해야 한다

하지만 이 쿼리 또한 제대로 동작하지 않았다

그 원인을 찾아

또 구글링으로 찾아본 결과

테이블 내에서 순서는 의미가 없다

라는 게 원인이었다

따라서, 서브쿼리를 통해

테이블로 취급받는

FROM (
	SELECT * FROM ORDER_TABLE
	ORDER BY ORDER_RANK
) o

이 부분은 ORDER BY 가 의미가 없다고 받아들인 것이다

이 해결법은 간단하게

FROM (
	SELECT * FROM ORDER_TABLE
	ORDER BY ORDER_RANK LIMIT 1000000
) o

LIMIT 으로 제한을 걸어 주면 되었고

이렇게 해서 동작하는 이유는

순서는 의미 없다고 인식하지만 개수까지 제한하면

의미가 있다고 받아 들여

덩달아 ORDER BY까지 동작하게 되는 것 같다

최종 쿼리


그렇게 해서 결국

마무리 짓나 싶었는데

사실 더 간단한 방법이 있었다 😅

SELECT
o.ORDER_SEQ,
GROUP_CONCAT(
CONCAT(
'{ITEM_TITLE:"', i.ITEM_TITLE,
'", ORDER_INFO:"',o.ORDER_INFO,
'", ORDER_RANK:"', o.ORDER_RANK, '"}') ORDER BY o.ORDER_RANK
) ITEM_LIST
FROM ORDER_TABLE o
JOIN ITEM_TABLE i ON o.ITEM_SEQ = i.ITEM_SEQ
GROUP BY o.ORDER_SEQ;

위 처럼

GROUP_CONCAT 함수에서

ORDER BY를 지원하고 있어서 이를 이용하면

이중 쿼리를 작성할 필요가 없었다고 한다...🙃

참고


MySQL / MariaDB 서브 쿼리 내의 order by 안 되는 현상 + 해결법
작업을 하다 보면 다루어야 할 데이터도 많아지고, 테이블도 많아집니다. 그에 따라서 사용하는 쿼리문이 길어지기도 합니다. 쿼리가 길어지다 보면 과거 심플하던 시절에는 없던 문제가 생기기도 하는데, 이번에 제가 발견한 케이스가 있어 공유하고자 합니다. 사용했던 쿼리의 형태는 아래와 같았습니다. 3개의 테이블을 A 테이블의 m_id를 중심으로 join하고, 그 결과값을 원하는 기준으로 정렬한 후에 특정 컬럼을 기준으로 group하는 쿼리입니다.
https://developthreefeet.tistory.com/10

'일지' 카테고리의 다른 글

[영문법] 동사(4) - 보충어  (0) 2021.05.12
[영문법] 동사(3) - 조동사  (0) 2021.02.28
[영문법] 동사(2) - 시제/상/태  (0) 2021.02.16
[영문법] 동사(1) - 문장의 구조  (0) 2021.02.13

댓글