오라클에서 mysql로 변환중인데 쿼리가 너무 복잡합니다.
조회수 2473회
오라클에서 mysql로 변환중입니다...
select
days.mdate ,
ifnull(login_cnt,0) as login_cnt ,
ifnull(logout_cnt,0) as logout_cnt
from ( select '2016-06-16' as mdate from ts_user where limit 1,1 ) days
left join ( select substr(vl_date,0,10) as mdate ,
sum(case when vl_login_yn = 'Y' then 1 else 0 end) login_cnt ,
sum(case when vl_login_yn != 'Y' then 1 else 0 end) logout_cnt
from
ts_visit_log
where substr(vl_date,0,10)
between ? and ?
group by substr(vl_date,0,10) ) log
on log.mdate = days.mdate
order by days.mdate asc
대체 이게 무슨말인가요?
1 답변
-
SQL의 구조는 다음과 같네요.
select ... from ( SUBQUERY1 ) mdate left join ( SUBQUERY2 ) log on log.mdate = days.mdate order by days.mdate asc
( SUBQUERY1 ) mdate
꼴은 SUBQUERY1의 결과를 mdate라는 이름의 테이블로 명명하겠다는 것입니다. 실제 테이블은 없고 임시로 존재하는 테이블이 됩니다.- select ... from
T1
left joinT2
onCONDITION
, 은 아시겠지만, T1(좌측)의 테이블을 기준으로 T2를 조인합니다. 만약 T1에 값이 있고 T2에 값이 없으면 T2에 해당하는 컬럼들은 NULL이 됩니다. 조인하는 기준값은on
절에서 조건을 기술합니다.
SQL문 설명
ifnull(login_cnt,0)
만약 login_cnt가 null 이면 0 아니면 login_cnt 값을 사용합니다.XXX as login_cnt
XXX의 결과(혹은 컬럼)을 컬럼 login_cnt로 부르겠다는 의미힙니다.
SUBQUERY1
select '2016-06-16' as mdate from ts_user where limit 1,1
주: SUBQUERY1은 크게 의미가 있는 것 갖지는 않네요. mdate라는 컬럼하나 있는데 그 값이 2016-06-16 한개 row가 있도록 만들었네요.
SQL문 설명
limit 1,1
결과의 첫번째 레코드부터 1개로 제한한다는 의미입니다.
SUBQUERY2
select substr(vl_date,0,10) as mdate , sum(case when vl_login_yn = 'Y' then 1 else 0 end) login_cnt , sum(case when vl_login_yn != 'Y' then 1 else 0 end) logout_cnt from ts_visit_log where substr(vl_date,0,10) between ? and ? group by substr(vl_date,0,10)
주: SUBQUERY2가 위의 SQL이네요.
SQL문 설명
substr(xxxx,0,10)
은 xxxx컬럼의 0번째부터 10글자를 추출한다는 의미입니다.case when vl_login_yn = 'Y' then 1 else 0 end
이것은 SQL의 선택문으로vl_login_yn
컬럼의 값이Y
이면 1로 하고, 그렇지 않으면 0으로 합니다.XXX between ? and ?
이 문장에서?
는 파라미터 바인딩을 해야 하는 위치를 의미합니다. 나중에 프로그램 코드에서 적용할 값을 제공(바인딩)하게 됩니다. SQL문의 뜻은 'XXX의 값이 첫번째 파라미터?
와 두번째 파라미터?
사이에 있어야 한다'입니다.group by XXX
은 XXX의 값이 같은 것끼리 레코드를 묶습니다.sum(...)
함수는 4번의group by
절에 의해 묶여진 레코드들에 대해서 연산하는 함수가 되겠습니다.
정리
특정기간안에 사용자 로그인횟수와 사용자 로그아웃 횟수를 계산한 임시테이블 log와 임시테이블 mdate를 조인해서,
[날짜,로그인횟수,로그아웃횟수]
를 계산하고, 날짜순으로 정렬한 것입니다.
댓글 입력