오라클에서 mysql로 변환중인데 쿼리가 너무 복잡합니다.


오라클에서 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

대체 이게 무슨말인가요?

  • 2016년 06월 16일에 수정됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 모바일 게임도 조금 만들어 봤습니다.
  • 2016년 06월 16일에 작성됨

  • 쿼리가 무슨 의미인지를 말씀하시는건가요? 배경설명이 더 필요합니다.    정두식   2016.6.16 19:03     
조회수 288


1 답변


좋아요
3
싫어요
채택취소하기

SQL의 구조는 다음과 같네요.

select ... 
  from ( SUBQUERY1 ) mdate 
  left join ( SUBQUERY2 ) log 
  on log.mdate = days.mdate
    order by days.mdate asc
  1. ( SUBQUERY1 ) mdate 꼴은 SUBQUERY1의 결과를 mdate라는 이름의 테이블로 명명하겠다는 것입니다. 실제 테이블은 없고 임시로 존재하는 테이블이 됩니다.
  2. select ... from T1 left join T2 on CONDITION, 은 아시겠지만, T1(좌측)의 테이블을 기준으로 T2를 조인합니다. 만약 T1에 값이 있고 T2에 값이 없으면 T2에 해당하는 컬럼들은 NULL이 됩니다. 조인하는 기준값은 on 절에서 조건을 기술합니다.

SQL문 설명

  1. ifnull(login_cnt,0) 만약 login_cnt가 null 이면 0 아니면 login_cnt 값을 사용합니다.
  2. 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문 설명

  1. 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문 설명

  1. substr(xxxx,0,10)은 xxxx컬럼의 0번째부터 10글자를 추출한다는 의미입니다.
  2. case when vl_login_yn = 'Y' then 1 else 0 end 이것은 SQL의 선택문으로 vl_login_yn 컬럼의 값이 Y이면 1로 하고, 그렇지 않으면 0으로 합니다.
  3. XXX between ? and ? 이 문장에서 ?는 파라미터 바인딩을 해야 하는 위치를 의미합니다. 나중에 프로그램 코드에서 적용할 값을 제공(바인딩)하게 됩니다. SQL문의 뜻은 'XXX의 값이 첫번째 파라미터?와 두번째 파라미터 ? 사이에 있어야 한다'입니다.
  4. group by XXX 은 XXX의 값이 같은 것끼리 레코드를 묶습니다.
  5. sum(...) 함수는 4번의 group by 절에 의해 묶여진 레코드들에 대해서 연산하는 함수가 되겠습니다.

정리

특정기간안에 사용자 로그인횟수와 사용자 로그아웃 횟수를 계산한 임시테이블 log와 임시테이블 mdate를 조인해서, [날짜,로그인횟수,로그아웃횟수]를 계산하고, 날짜순으로 정렬한 것입니다.

  • 2016년 06월 16일에 작성됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.

  • 아이고 감사합니다 너무 많은 도움이 되었습니다^^    김영광   2016.6.20 16:44     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close