1.
<select id="getTagListWithConnectedItemCount" parameterType="Integer" resultType="TagVo">
SELECT
TAG.IDX,
TAG.DEPTH_TYPE,
TAG.DEPTH1_IDX,
TAG.DEPTH2_IDX,
TAG.ITEM_ORDER,
TAG.TAG_NAME_KOR,
TAG.TAG_NAME_ENG,
TAG.IS_SHOW,
COUNT(EXHIBIT_TAG.IDX) AS CONNECTED_ITEM_COUNT,
TAG.REG_DTTM
FROM
TB_TAG TAG
LEFT JOIN TB_EXHIBIT_TAG EXHIBIT_TAG ON EXHIBIT_TAG.TAG_IDX = TAG.IDX
WHERE
TAG.DEPTH_TYPE != 1
<if test="depth1_idx != null">
AND TAG.DEPTH1_IDX = #{depth1_idx}
</if>
GROUP BY
TAG.IDX, TAG.DEPTH_TYPE, TAG.DEPTH1_IDX,
TAG.DEPTH2_IDX, TAG.ITEM_ORDER, TAG.TAG_NAME_KOR,
TAG.TAG_NAME_ENG, TAG.IS_SHOW, TAG.REG_DTTM
ORDER BY
TAG.DEPTH1_IDX, TAG.DEPTH2_IDX, TAG.ITEM_ORDER;
</select>
이렇게 다른분이 올린 마이바티스 SQL문 보니 일단 테이블은 TB_TAG,TB_EXHIBIT_TAG 있는데
Group by문에는 왜 TB_TAG 테이블에 관한 필드만 적고 Count()문에는 TB_EXHIBIT_TAG 했는지 헷갈렸다.
해석해보면 일단 Left Join 이니 TB_TAG 데이터 다 가져오는데 예를들어 Group By없다하고
TB_TAG 에 pk가 1인 데이터 TB_EXHIBIT_TAG에 연관된 데이터가 pk 1,3,6,9 있을시 결과는 이렇게 TB_TAG 데이터 중복으로 나온다. 그래서 GROUP_BY문에 TB_TAG 필드들 적은거고,
Count문은 말그대로 조인했을때 왼쪽 테이블 각 해당 행마다 오른쪽 테이블에 연관된 데이터가 몇개인지 구한거다.
TB_TAG pk 1데이터 / TB_EXHIBIT_TAG pk 1 데이터,
TB_TAG pk 1데이터 / TB_EXHIBIT_TAG pk 3 데이터,
TB_TAG pk 1데이터 / TB_EXHIBIT_TAG pk 6데이터,
TB_TAG pk 1데이터 / TB_EXHIBIT_TAG pk 9데이터
클로드한테 물어보니 위에 쿼리문 결과랑 같으면서 다른 쿼리방식인 서브쿼리 이용한게 있다.
이렇게 TB_EXHIBIT_TAG을 서브쿼리했다.
SELECT
TAG.IDX,
TAG.DEPTH_TYPE,
TAG.DEPTH1_IDX,
TAG.DEPTH2_IDX,
TAG.ITEM_ORDER,
TAG.TAG_NAME_KOR,
TAG.TAG_NAME_ENG,
TAG.IS_SHOW,
COALESCE(ITEM_COUNT.CONNECTED_ITEM_COUNT, 0) AS CONNECTED_ITEM_COUNT,
TAG.REG_DTTM
FROM
TB_TAG TAG
LEFT JOIN (
SELECT
TAG_IDX,
COUNT(*) AS CONNECTED_ITEM_COUNT
FROM
TB_EXHIBIT_TAG
GROUP BY
TAG_IDX
) ITEM_COUNT ON ITEM_COUNT.TAG_IDX = TAG.IDX
WHERE
TAG.DEPTH_TYPE != 1
<if test="depth1_idx != null">
AND TAG.DEPTH1_IDX = #{depth1_idx}
</if>
ORDER BY
TAG.DEPTH1_IDX, TAG.DEPTH2_IDX, TAG.ITEM_ORDER
또 다른 방법인 Group by 사용 안하고 중복제거 DISTINCT를 이용하는 방법이 있다
<select id="getTagListWithConnectedItemCount" parameterType="Integer" resultType="TagVo">
SELECT DISTINCT
TAG.IDX,
TAG.DEPTH_TYPE,
TAG.DEPTH1_IDX,
TAG.DEPTH2_IDX,
TAG.ITEM_ORDER,
TAG.TAG_NAME_KOR,
TAG.TAG_NAME_ENG,
TAG.IS_SHOW,
(SELECT COUNT(EXHIBIT_TAG.IDX) FROM TB_EXHIBIT_TAG EXHIBIT_TAG WHERE EXHIBIT_TAG.TAG_IDX = TAG.IDX) AS CONNECTED_ITEM_COUNT,
TAG.REG_DTTM
FROM
TB_TAG TAG
WHERE
TAG.DEPTH_TYPE != 1
<if test="depth1_idx != null">
AND TAG.DEPTH1_IDX = #{depth1_idx}
</if>
ORDER BY
TAG.DEPTH1_IDX, TAG.DEPTH2_IDX, TAG.ITEM_ORDER;
</select>
2. GROUP_CONCAT , CONCAT() , SEPARATOR
SELECT
IDX,
TYPE,
TITLE_KOR,
TITLE_ENG,
START_DATE,
EXPIRE_DATE,
REG_DTTM,
UPD_DTTM,
LCLASS_TYPE,
(
SELECT
GROUP_CONCAT(CONCAT('#', TAG.TAG_NAME_KOR) ORDER BY TAG.DEPTH1_IDX, TAG.DEPTH2_IDX, TAG.ITEM_ORDER ASC SEPARATOR ' ') AS SELECT_TAG_NAME_KOR
FROM
TB_EXHIBIT_TAG EXHIBIT_TAG
LEFT JOIN TB_TAG TAG ON TAG.IDX = EXHIBIT_TAG.TAG_IDX
WHERE
TB_EXHIBIT_CONTENTS.IDX = EXHIBIT_TAG.EXHIBIT_CONTENTS_IDX
GROUP BY
EXHIBIT_TAG.EXHIBIT_CONTENTS_IDX
) AS SELECT_TAG_NAME_KOR
FROM TB_EXHIBIT_CONTENTS
WHERE TYPE=#{type}
GROUP_CONCAT 함수는 MySQL에서 사용할 수 있는 집계 함수로, 그룹화된 결과를 하나의 문자열로 결합해줍니다. 이 함수는 여러 행의 값을 하나의 문자열로 결합하는 데 유용합니다.
CONCAT()는 MySQL의 CONCAT 함수를 사용하여 문자열을 결합하는 부분입니다. 이 함수는 주어진 여러 문자열을 하나의 문자열로 합치는 역할을 합니다.
TAG.TAG_NAME_KOR이 태그A라면, CONCAT('#', TAG.TAG_NAME_KOR)는 #태그A가 됩니다.
SEPARATOR는 MySQL의 GROUP_CONCAT 함수에서 사용되는 옵션으로, 여러 값들을 결합할 때 각각의 값들 사이에 들어갈 구분자를 지정합니다. 기본적으로 GROUP_CONCAT 함수는 쉼표(,)를 사용하여 값들을 구분하지만, SEPARATOR를 사용하여 원하는 구분자를 지정할 수 있습니다.
(밑에 예시 보면 #태크A #태크B 이렇게 공백을 넣어주는 역활을 한다)
위에 코드 예시
'플랫폼엘 정리or해석' 카테고리의 다른 글
css,JavaScript관련 (0) | 2024.07.18 |
---|---|
커스텀 어노테이션 적용후,인터셉터에 적용하기 (0) | 2024.07.12 |
MySql의 암호화,복호화 (0) | 2024.07.04 |
XSS 공격 방지용 XssFilter (0) | 2024.06.25 |
Json 코드 해석 (0) | 2024.06.25 |