안녕하세요 신입개발자입니다.
결과값 출력은 했지만 쿼리문이 깔끔하지 못한 것 같습니다 ㅠㅠ
중복되는 부분이 있거나 연산시간에 비효율적인 부분이 있는지,
더 좋은 방식으로 쿼리를 짤 수 없을지 조언을 얻고자 이렇게 글을 남기게 되었습니다.
이 쿼리문의 목적은
재활용쓰레기 [배출 장소 / 배출한 회원의 이름 / 쓰레기 수거 기기의 아이디]를 가져오기 위함입니다.
우선 종이테이블과 플라스틱테이블에 입력된 정보를 모두 가져오고자 UNION을 사용하였고
배출 장소, 회원 이름, 기기 아이디를 가져오기 위해
종이테이블과 플라스틱테이블 정보로는 얻을 수 없어
추가로 서브쿼리를 작성했습니다.
테이블 USERS (사용자 테이블) REGION (장소 테이블) EQUIPMENT (장비 테이블) WEIGHT (종이수거 테이블) COLLECTION_CNT (플라스틱 테이블) SELECT @ROWNUM := @ROWNUM + 1 ROWNUM , SUB.* FROM ( SELECT J_USR_ID userId ,J_EQUIPMENT_ID equipmentId ,J_WEIGHT_DTTM insertDttm ,J_WEIGHT weightNcnt ,PP_PAPER_PRICE price ,PP_POINT ecoPoint , ( SELECT DISTINCT ECO_REGION_ID FROM EQUIPMENT WHERE WEIGHT.J_EQUIPMENT_ID = EQUIPMENT.eco_equipment_id LIMIT 1 )regionArea /*+ 장소아이디를 가져오기위한 서브쿼리*/ , ( SELECT DISTINCT ECO_REGION_NM FROM REGION WHERE REGION.ECO_REGION_ID = regionArea LIMIT 1 )ecoRegionNm /*+ 장소아이디를 통해 장소명을 가져오기 위한 쿼리*/ , ( SELECT DISTINCT USER_NAME FROM USERS WHERE USERS.USER_ID=WEIGHT.J_USR_ID LIMIT 1 )userName /*+ 회원아이디로 회원 이름을 조회하기 위한 쿼리*/ , ( SELECT DISTINCT USER_GRADE FROM USERS WHERE USERS.USER_ID=WEIGHT.J_USR_ID LIMIT 1 )userGrade /*+ 회원아이디로 회원 등급을 조회하기 위한 쿼리*/ FROM WEIGHT WHERE 1=1 UNION SELECT ECHO_USR_ID userId ,ECHO_EQUIPMENT_ID equipmentId ,J_START_DTTM insertDttm ,J_CNT weightNcnt ,ECHO_PRICE price ,ECHO_POINT ecoPoint , ( SELECT DISTINCT ECO_REGION_ID FROM EQUIPMENT WHERE COLLECTION_CNT.ECHO_EQUIPMENT_ID = EQUIPMENT.ECO_EQUIPMENT_ID LIMIT 1 )regionArea /*+ 장소아이디를 가져오기위한 서브쿼리*/ , ( SELECT DISTINCT ECO_REGION_NM FROM REGION WHERE REGION.ECO_REGION_ID = regionArea LIMIT 1 )ecoRegionNm /*+ 장소아이디를 통해 장소명을 가져오기 위한 쿼리*/ , ( SELECT DISTINCT USER_NAME FROM USERS WHERE USERS.USER_ID=COLLECTION_CNT.ECHO_USR_ID LIMIT 1 )userName /*+ 회원아이디로 회원 이름을 조회하기 위한 쿼리*/ , ( SELECT DISTINCT USER_GRADE FROM USERS WHERE USERS.USER_ID=COLLECTION_CNT.ECHO_USR_ID LIMIT 1 )userGrade /*+ 회원아이디로 회원 등급을 조회하기 위한 쿼리*/ FROM COLLECTION_CNT, (SELECT @ROWNUM := 0) R ) SUB WHERE 1=1 ORDER BY insertDttm DESC
아래 사진은 결과값입니다
감사합니다 :)
1. 테이블이 정상적이라면
- Distinct 나 LIMIT 1 은 불필요 합니다.
- 서브쿼리 보다는 조인으로 풀어야 합니다.
- Union 이 아니라 Union All 을 사용해야 합니다.
2. DB 버전이 최신이라면 (MySQL 8.0 이상)
- @ROWNUM 보다는 ROW_NUMBER() 를 이용하는게 좋습니다.
SELECT ROW_NUMBER() OVER(ORDER BY a.insertDttm DESC) rn
, a.userid
, a.equipmentid
, a.insertdttm
, a.weightncnt
, a.price
, a.ecopoint
, b.eco_region_id
, c.eco_region_nm
, d.user_name
, d.user_grade
FROM (SELECT j_usr_id userid
, j_equipment_id equipmentid
, j_weight_dttm insertdttm
, j_weight weightncnt
, pp_paper_price price
, pp_point ecopoint
FROM weight
UNION ALL
SELECT echo_usr_id userid
, echo_equipment_id equipmentid
, j_start_dttm insertdttm
, j_cnt weightncnt
, echo_price price
, echo_point ecopoint
FROM collection_cnt
) a
INNER JOIN equipment b
ON a.equipmentid = b.eco_equipment_id
INNER JOIN region c
ON b.eco_region_id = c.eco_region_id
INNER JOIN users d
ON a.userId = d.user_id
;
감사합니다 :)