서브쿼리를 줄이고 싶습니다. 0 5 655

by le_penseur [SQL Query] 서브쿼리 조인 [2019.11.06 10:32:11]


서브쿼리를 최소화하고 싶은데 도저히 감이 안와서 감히 질문 올립니다.
조인을 사용해봤는데 방법이 틀렸는지 결과값이 하나만 나옵니다. (아마 방법의 문제 같습니다.)
질문을 어떻게 해야할지도 감이 안옵니다. 요즘 너무 슬럼프네요.
ground 테이블에서 여러 테이블의 데이터를 가져오는 구조입니다.
어떤 구조로 짜야 적당할지 질문 올립니다...ㅠㅠ
MySQL입니다.

select 
	*,
	(select name from city where idx = ground.city_idx) as city_name,
	(select country_idx from city where idx = ground.city_idx) as country_idx,
	(select name from country where idx = country_idx) as country_name,
	(select count(*) from reviews where ground_idx = ground.idx and review_type = 0) as review_count,
	(SELECT GROUP_CONCAT(file_url separator '|') FROM files WHERE TYPE = 'image' AND reference_table = 'ground' AND identity = 'thumb' AND reference_idx = '1') as thumb_list_idx,
	round((select avg(score) from reviews where ground_idx = ground.idx and review_type = 0), 1) as review_score
from 
	ground
where 
	viewState = 1

 

by le_penseur [2019.11.06 10:34:36]

그 외에 부족한 부분 첨언해주신다면 감사히 배우겠습니다.


by 우리집아찌 [2019.11.06 10:59:59]

file 태이블은 ground 태이블이랑 관계가 어찌 되나요?


by le_penseur [2019.11.06 15:15:47]

관계를 따로 맺은건 없고, type과 identity, reference_table, reference_idx로 가상의 키를 잡았습니다 !


by 마농 [2019.11.06 11:04:13]

Select 절의 서브쿼리는 스칼라서브쿼리라고 합니다.
이는 아우터 조인으로 변경 가능하며,
테이블간의 관계가 필수 관계라면 이너조인이 가능합니다.
예를 들어 city_idx 가 필수 값이라면 이너조인으로 바꾸시면 됩니다.

reviews, files 의 경우엔 ground 와 1:다 관계이고 필수가 아닌 선택의 관계네요.
이 부분은 전체 쿼리가 페이징 처리가 된다면?
즉 한페이지만 표시하는 쿼리라고 한다면? (예 : LIMIT 0, 10)
스칼라서브쿼리를 유지하는 것도 좋습니다.
그게 아니라 전체 자료가 조회되어야 한다면?
다 집합을 집계하여 1집합으로 만들어 1:1 조인하시면 됩니다.

SELECT a.*
     , b.name AS city_name
     , c.name AS country_name
     , d.review_count
     , d.review_score
     , e.thumb_list_idx
  FROM ground a
  LEFT OUTER JOIN city b
    ON b.idx = a.city_idx
  LEFT OUTER JOIN country c
    ON c.idx = b.country_idx
  LEFT OUTER JOIN
       (SELECT ground_idx
             , COUNT(*)             review_count
             , ROUND(AVG(score), 1) review_score
          FROM reviews
         WHERE review_type = 0
         GROUP BY ground_idx
        ) d
    ON a.idx = d.ground_idx
  LEFT OUTER JOIN
       (SELECT reference_idx
             , GROUP_CONCAT(file_url SEPARATOR '|')
          FROM files
         WHERE type     = 'image'
           AND identity = 'thumb'
           AND reference_table = 'ground'
         GROUP BY reference_idx
        ) e
    ON a.idx = e.reference_idx
 WHERE a.viewState = 1
;

 


by le_penseur [2019.11.06 15:16:29]

작성해주신 소중한 쿼리 하나하나 분석해보면서 배워가겠습니다.

정말 감사합니다...!

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