sql UNION 쿼리문 조언 부탁드립니다 0 2 1,365

by 핏슈 [SQL Query] MySQL [2022.03.24 16:04:39]


결과값.png (96,433Bytes)

안녕하세요 신입개발자입니다.

결과값 출력은 했지만 쿼리문이 깔끔하지 못한 것 같습니다 ㅠㅠ

중복되는 부분이 있거나 연산시간에 비효율적인 부분이 있는지,

더 좋은 방식으로 쿼리를 짤 수 없을지 조언을 얻고자 이렇게 글을 남기게 되었습니다.

 

이 쿼리문의 목적은

재활용쓰레기 [배출 장소 / 배출한 회원의 이름 / 쓰레기 수거 기기의 아이디]를 가져오기 위함입니다.

우선 종이테이블과 플라스틱테이블에 입력된 정보를 모두 가져오고자 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

 

아래 사진은 결과값입니다

 

감사합니다 :)

 

 

by 마농 [2022.03.25 00:57:13]

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
;

 


by 핏슈 [2022.03.25 09:45:38]

감사합니다 :)

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입