728x90
반응형

통계 쿼리는 조금 어려울 수도 쉬울 수도 있을 것 같습니다

하지만 대부분의 사람들은 어렵다고 할 것입니다

저 또한 그렇게 느끼고 있고요

 

한번 같이 공부하면서 알아보도록 하겠습니다

 

 

결과셋을 하나의 행으로 데이터 조회하기

 

통계 쿼리의 가장 기본인 결과셋을 하나의 행으로 만드는 것을 우선 해보겠습니다

행 그룹에서 값을 가져와서 그룹당 단일 행의 열로 변환하려고 합니다.

예를 들어 각 부서의 사원수를 표시하는 결과 셋이 있다고 해봅시다

 

 

아래와 같은 결과 셋을 하나행으로 보이도록 출력을 다시 재구성하려고 합니다.

통계쿼리1
결과셋을 하나의행으로 만들어보자

 

이 방법은 통계 쿼리에 자주 사용하는 방법이며 

가장 기초적인 방법의 예문으로 만들려고 합니다

 

이것을 바탕으로 응용해서 적용해보시길 바랍니다

 

 

우선 테이블에 어떤 데이터가 들어있는지 한번 확인해봅시다.

 

SELECT deptno FROM emp;

 

아래와 같이 데이터가 들어있으며, 총 14개의 행이 있습니다

 

통계쿼리2
원본 테이블 데이터 정보

 

이 데이터를 각 부서의 사원수를 구하기 위해서는

아래와 같이 일반적으로 생각하게 될 것입니다

하지만 이 데이터는 한 행에 출력이 않아 통계 쿼리로는 부적합합니다

그래서 하나 행으로 조회하는 방법을 알아보는 것이 최우선입니다 

 

SELECT deptno, coount(*) AS CNT FROM EMP GROUP BY deptno;

 

 

하나의 행으로 출력하는 과정을 알아보도록 하겠습니다

아래의 코드를 분석해 봅시다

 

 

select deptno,
       case when deptno=10 then 1 else 0 end as deptno_10,
       case when deptno=20 then 1 else 0 end as deptno_20,
       case when deptno=30 then 1 else 0 end as deptno_30
  from emp
 order by 1

 

 

위의 코드로 아래와 같이 조회되는 것을 확인할 수 있습니다

위의 DEPTNO 컬럼은 가독성을 위한 값이니 참고하시기 바랍니다.

CASE WHEN THEN ELSE END를 활용해서 한 컬럼에 대해서 값을 출력합니다 

그 값은 간단합니다 DEPTNO가 10이면 1을 주고 나머지는 0을 부여하게 됩니다.

그리고 두 번째 컬럼은 DEPTNO가 20, 세번째 컬럼은 DEPTNO가 30으로

아래의 데이터가 조회됩니다  그러나 아직은 조금 미흡합니다

아직 행이 하나가 아니기 때문이지요

 

그럼 조금 수정해보겠습니다

 

통계쿼리3
case문으로 쿼리 조회

 

 

아래의 코드로 합계결과 값은 하나의 행으로 반환하였습니다

위의 결과 값에서 집계 함수 SUM을 사용하여 각 DEPTNO의 발생 횟수를 계산합니다

 

 

 select sum(case when deptno=10 then 1 else 0 end) as deptno_10,
       sum(case when deptno=20 then 1 else 0 end) as deptno_20,
       sum(case when deptno=30 then 1 else 0 end) as deptno_30
  from EMP;

 

아래와 같이 최종 결과가 출력됩니다 

 

 

통계쿼리4
최종 결과

 

 

하지만 아직 조금 부족합니다 그 이유는 한 테이블에서 CASE문을 전체를 적용해서 

시스템상 성능 부하가 올 수 있습니다 그리고 단순히 CASE 표현식을 합산하는 방법을 이기 때문입니다

지금은 데이터가 많이 없기 때문에 이 같은 방법을 해도 문제가 없지만 데이터가 몇만 건씩 넘어간다면

문제가 발생할 것입니다

다른 방법을 알아보도록 하겠습니다

 

 

select case when deptno=10 then empcount else null end as deptno_10,
  case when deptno=20 then empcount else null enD as deptno_20,
  case when deptno=30 then empcount else null end as deptno_30
from (
        select deptno, count(*) as empcount
          from emp
         group by deptno
     ) x;

 

 

아래의 코드를 자세히 보시면

처음에 COUNT 함수를 사용했던 것을 기억하실 것입니다

그 쿼리를 인라인 뷰로 사용하여 부서당 사원수를 생성합니다

그럼 그 결과 값은 아래와 같이 출력되는 것을 확인할 수 있습니다

 

이 방법은 인라인 뷰로 먼저 생성된 데이터가 3개의 행이므로

CASE문 실행할 경우 전체 행을 읽지 않고 3개의 행만으로

결과를 출력할 수 있습니다 

 

 

통계쿼리5
인라인 뷰 활용 예

 

그런 다음 MAX 함수로 열을 하나의 행으로 축소를 합니다

아래의 코드를 확인해 봅시다

 

select max(case when deptno=10 then empcount else null end) as new_deptno_10,
       max(case when deptno=20 then empcount else null end) as new_deptno_20,
       max(case when deptno=30 then empcount else null end) as new_deptno_30
from (
        select deptno, count(*) as empcount
          from emp
         group by deptno
     ) x;

 

결과 값은 아래와 같이 출력되는 것을 확인할 수 있습니다

 

 

통계쿼리6
성능강화 쿼리 적용 결과값

 

아래는 사례별로 통계 쿼리를 작성하는 것을 포스팅 연결하였습니다

그리고 마지막에는 통계쿼리 응용문제가 있으니

확인하셔서 공부하는데 도움이 되셨으면 합니다 감사합니다

 

 

2022.08.08 - [IT_Web/Oracle] - Oracle mybatis 활용 DECODE CASE GROUP BY ROLLUP 회원 통계 쿼리 월별 분기별 연도별

 

Oracle mybatis 활용 DECODE CASE GROUP BY ROLLUP 회원 통계 쿼리 월별 분기별 년도별

회원 월별 분기별 년도별 통계 쿼리 오늘은 회원별 통계 쿼리를 알아보도록 하겠습니다 mybatis를 활용해서 여러 조건문을 한번에 처리하는 쿼리를 작성하도록 하겠습니다 selectType을 프론트 단에

tantangerine.tistory.com

 

 

2022.08.09 - [IT_Web/Oracle] - oracle 회원 가입 증가 현황 DECODE 통계 쿼리 CASE, GROUP BY 활용

 

oracle 회원 가입 증가현황 DECODE 통계 쿼리 CASE, GROUP BY 활용

회원 가입 증가 현황 통계 쿼리 회원 가입 통계 쿼리를 만들어 보려고 합니다 저도 아직 익숙하지 않아서 조금 더 좋은 방법 있다면 댓글 남겨주세요~ 등록일(REG_DT)을 기준으로 신규회원 가입현

tantangerine.tistory.com

 

2022.08.10 - [IT_Web/Oracle] - oracle 상품 판매 통계 쿼리 union all case group by 활용

 

oracle 상품 판매 통계 쿼리 union all case group by 활용

상품 판매 통계 쿼리 오늘은 상품 판매 통계 쿼리를 만들어 보겠습니다 상품은 여러 종류가 있습니다 그것을 어떻게 구분할지는 스스로가 정해야겠지요 아래에서는 상품구분을 단순하게 알파

tantangerine.tistory.com

 


 

 


 

 

사례로 보는 통계 쿼리 문

* 아래의 문제는 쿼리문을 집중해서 보시고 이렇게도 쿼리를 작성할 수 있구나 하고

생각해보는 시간이 되었으면 합니다

 

 

 

 

HP라는 제품은 너무 많은 등급을 가지고 있어 제품별로 분석하기를 원하고, ‘LD’라는 제품은 등급의 수가 적고 중요하므로 등급별로 분석하기를 원하며, ‘PP’라는 제품은 다양한 등급을 가지고 있으나 ‘P530C’라는 등급은 전략적으로 관리하고자 하여 등급별로 분석하고, 나머지는 기타로 모아주기를 원한다고 생각하자

 

이런 경우에는 CASE와 GROUP BY를 활용하여 풀어보자

 

SELECT

  CASE

    WHEN 제품 = ‘HP’ THEN 제품

    WHEN 제품 = ‘LD’ THEN 등급 ,

    WHEN 등급 = ‘P530C’ THEN 등급

    ELSE ’기타‘

  END

  , SUM(총매출), SUM(총수량).....

FROM 매출테이블

WHERE 매출일자 LIKE ’9808%’

GROUP BY

  CASE

    WHEN 제품 = ‘HP’ THEN 제품

    WHEN 제품 = ‘LD’ THEN 등급 ,

    WHEN 등급 = ‘P530C’ THEN 등급

    ELSE ’기타‘

  END

 


 

SALE_HIST 테이블을 참조하여 ‘PENCIL’ 총판매금액과 01번 사업장의 총판매금액과

ERASER를 판매하고 있는 사업장의 총판매 금액을 출력하고 그 나머지를 기타로 묶어 총판매금액을 출력하시오

통계쿼리7
SALE_HIST 테이블 데이터 정보

 

SELECT

  CASE

    WHEN SALE_ITEM = 'PENCIL' THEN SALE_ITEM

    WHEN SALE_ITEM = 'ERASER' THEN SALE_SITE

    WHEN SALE_SITE = 01 THEN SALE_SITE

    ELSE '기타'

  END AS 특별관리항목

  , SUM(SALE_AMT) AS 총판매금액

FROM SALE_HIST

  GROUP BY

    CASE

      WHEN SALE_ITEM = 'PENCIL' THEN SALE_ITEM

      WHEN SALE_ITEM = 'ERASER' THEN SALE_SITE

      WHEN SALE_SITE = 01 THEN SALE_SITE

      ELSE '기타'

    END

 

통계쿼리8
상품별 총판매금액 통계쿼리

 

 


 

 

 

TEST100 테이블을 참조하여 C2에 해당하는 값의 비율을 구하여라

 

통계쿼리9
TEST100 테이블 데이터 정보

 

SELECT C1, C2

, ROUND(RATIO_TO_REPORT(C2) OVER(),2) * 100 AS PER

FROM TEST100

 

통계쿼리10
TEST100 상품별 비율

 


 

 

TEST35 테이블을 참조하여 KEY1은 부서라고 생각하고 KEY2의 A는 판매액 B는 매입액이라고 할 때

부서별 판매액과 매입액의 차에 대한 값(수익)을 구하고 차액의 비율을 구하시오

 

통계쿼리11
TEST35 테이블 데이터 정보

 

 

SELECT

  CASE WHEN KEY1 IS NOT NULL THEN KEY1 ELSE '합계' END AS KEY1

  ,  SUM(CASE WHEN KEY2 = 'A' THEN AMT ELSE 0 END) AS 판매액

  ,  SUM(CASE WHEN KEY2 = 'B' THEN AMT ELSE 0 END) AS 매입액

  ,  SUM(CASE WHEN KEY2 = 'A' THEN AMT ELSE -AMT END) AS 수익

  ,  ROUND(SUM(CASE WHEN KEY2='A' THEN AMT ELSE -AMT END)

                        / SUM(CASE WHEN KEY2='A' THEN AMT END)*100 ) AS PER

FROM (SELECT KEY1, KEY2, SUM(AMT) AMT

               FROM TEST35

               GROUP BY ROLLUP(KEY1),  KEY2

               )

GROUP BY KEY1;

 

 

통계쿼리12
부서 판매액 차액 비율

 


 

 

Temp를 이용한 문제를 풀어보자

Temp에 있는 직원들을 부서별 직급별로 SALARY 합을 보려 한다 이때 부서별로 직급들이 동일행에 나오도록

보여주고 부서별 전체 급여 그리고 PER컬럼의 전체 부서 급여 합계 비율을 구하여라

 

 

통계쿼리13
TEMP 테이블 데이터 정보

 

 

SELECT CASE WHEN DEPTNO IS NOT NULL THEN DEPTNO ELSE '합계' END DEPTNO

                 , SUM(A.부장) 부장, SUM(A.차장) 차장, SUM(A.과장) 과장

                 , SUM(A.대리) 대리, SUM(A.사원) 사원, SUM(A.수습) 수습, SUM(A.PER) 전체급여비율

                 , SUM(A.SAL) 부서별급여합계

FROM (SELECT DEPT_CODE DEPTNO, SALARY SAL

                               , SUM(CASE WHEN LEV = '부장' THEN SALARY ELSE 0 END) 부장

                               , SUM(CASE WHEN LEV = '차장' THEN SALARY ELSE 0 END) 차장

                               , SUM(CASE WHEN LEV = '과장' THEN SALARY ELSE 0 END) 과장

                               , SUM(CASE WHEN LEV = '대리' THEN SALARY ELSE 0 END) 대리

                               , SUM(CASE WHEN LEV = '사원' THEN SALARY ELSE 0 END) 사원

                               , SUM(CASE WHEN LEV = '수습' THEN SALARY ELSE 0 END) 수습

                               , ROUND(RATIO_TO_REPORT(SALARY) OVER (),2) * 100 AS PER

                               , SUM(SALARY)

              FROM TEMP

              GROUP BY DEPT_CODE, SALARY, LEV

              ) A

GROUP BY ROLLUP(DEPTNO)

ORDER BY DEPTNO

 

 

통계쿼리14
부서별 전체 급여 비율

 


 

 

TEST02 테이블의 자료를 이용해 최대 CRATE를 가지는 일자의 AMT와 최소 CREATE를 가지는 일자의 AMT를 읽어오는 문장을 출력하시오

 

통계쿼리15
TEST02 테이블 정보

 

 

SELECT distinct

  LAST_VALUE(AMT) OVER( ORDER BY CRATE

                                    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) MAX_VAL

  , FIRST_VALUE(AMT) OVER( ORDER BY CRATE

                                       ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) MIN_VAL

FROM TEST02

 

 

통계쿼리16
최대 최소 금액출력

 

                    


 

 

이렇게 통계 쿼리를 작성법을 알아보았습니다

조금이나마 도움이 되었으며 합니다

저도 통계 쿼리를 접할 때 많이 힘들었던 적이 있어서 이렇게 준비하게 되었습니다

그럼 앞으로 공부할 날이 너무나도 많기에 힘내시고 

같이 파이팅합시다

 

그럼 다음 포스팅도 기대해주세요!

 

728x90
반응형
728x90
반응형

 

회원 가입 증가 현황 통계 쿼리

 

 

회원 가입 통계 쿼리를 만들어 보려고 합니다

저도 아직 익숙하지 않아서 조금 더 좋은 방법 있다면

댓글 남겨주세요~

 

 

등록일(REG_DT)을 기준으로 신규회원 가입현황을 알아볼 수 있게 쿼리를 만들어 봅시다

밑의 쿼리는 금일 신규가입 현황을 볼 수 있는 쿼리입니다

param값을 todayoneDay를 받아서 처리하기 때문에

기간별 신규회원 증가 수를 확인할 수 있습니다

 

여기 가장 중요한 것은 서브 쿼리를 만들 때 등록일 기준으로 카운팅을 하고 등록일 시분초로 기준으로

데이터를 추출하여 GROUP BY를 해야 한다는 것입니다

 

그럼 아래의 쿼리를 천천히 봅시다~

 

SELECT 
    decode(MB_TPCD, '0010', '일반', '0020', '개인사업자', '0030',  '법인', '0040', '단체') as memberType,
    REG_CNT AS total
  FROM (
        SELECT 
            T1.MB_TPCD
            , NVL(REG_DT, #{today}) AS REG_DT
            , REG_CNT
          FROM (
                SELECT
                    MBM.Mb_TPCD
                    , A.REG_DT
                    , COUNT(A.REG_DT) AS REG_CNT
                  FROM (
                        SELECT 
                            /* 오늘날짜를 할당해서 기간동안의 증가 현황을 볼 수 있게 추출한다 */
                            TO_CHAR(REG_DT, 'YYYYMMDD') AS REG_DT
                            , MB_TPCD
                        FROM MB_MST
                        /* 오늘날짜를 할당해서 기간동안의 증가 현황을 볼 수 있게 추출한다 */
                        WHERE REG_DT BETWEEN TO_DATE(#{today} || '000000', 'YYYYMMDDHH24MISS') AND TO_DATE(#{oneDay} || '235959', 'YYYYMMDDHH24MISS')                                    
                        ) AS MBM,
                GROUP BY MBM.MB_TPCD, MBM.REG_DT
               ) AS T1
       ) AS VW1
 /* 금일이나 특정날을 지정해서 증가 현황을 확인할 수 있다 */
 WHERE VW1.REG_DT BETWEEN TO_DATE(#{today}) AND TO_DATE(#{oneDay})                                    
 ORDER BY MB_TPCD ASC

 

이렇게 신규 회원 증가 현황 쿼리를 알아보았습니다

금일도 괜찮고 기간별로도 조회할 수 있는 쿼리를 만들어 보았습니다

통계는 비즈니스적인 요소가 많이 필요하다고 생각합니다

 

회원 통계는 그렇게 많이 필요하지 않지만

어떤 상품에 대한 판매현황, 광고효과 분석 통계 쿼리를 만들기 위해서는

조금은 더 복잡한 쿼리가 되지 않을까 생각합니다

그럼 오늘은 여기까지 하고 다음 포스팅을 기대해주세요

 

언제나 우리의 대모험을 위해

오늘도 한 걸음씩 나아갑시다

 

그럼 파이팅!!

728x90
반응형
728x90
반응형

회원 월별 분기별 년도별 통계 쿼리

 

 

오늘은 회원별 통계 쿼리를 알아보도록 하겠습니다

mybatis를 활용해서 여러 조건문을 한번에 처리하는 쿼리를 작성하도록 하겠습니다

 

selectType을 프론트 단에서 month, quarter, recentYear의 값들을 받아옵니다

그리고 회원 테이블인 MB_MST에서 등록일자와 회원구분에 대한 값을 서브쿼리로 작성합니다

 

회원 구분별로 GROUP BY ROLLUP을 하여 진행한다는 것이 핵심입니다

 

GROUP BY ROLLUP 밑에 포스팅도 걸어 놓았습니다

 

2020.03.08 - [IT_Web/Oracle] - Oracle ROLLUP, CUBE, GROUPING(), GROUPING SETS(), GROUP_ID() 함수 개념

 

Oracle ROLLUP, CUBE, GROUPING(), GROUPING SETS(), GROUP_ID() 함수 개념

ROLLUP ROLLUP은 SELECT한 컬럼들을 GROUP BY 절과 함께 사용하게 되면 소계를 구할 수 있다 그 과정에는 CARTESIAN PRODUCT를 이용한 결과물들이란 것을 알아두자 또 한 ROLLUP의 인수는 계층 구조이므로 인수

tantangerine.tistory.com

 

 

그럼 실제 코드 사례를 한번 보도록 하겠습니다

자세히 보시면 등록일로 하여 컨트롤 하는 것을 보실 수 있습니다

 

 

<select id="selectNewMemberDetail" parameterType="Map" resultType="Map">
    SELECT 
        /*  DECODE를 활용해서 회원구분별로 누적 합계를 추출한다 */
        decode(CD_ID, '0010', 'normalSum', '0020', 'individualSum', '0030',  'organizationSum', '0040', 'affilicorpSum','membertypeSum') as memberType
    <choose>
        <when test="selectType == 'month'"> /*  DECODE 함수를 활용해서 월별로 필드를 추출한다 */
            , count(decode(to_char(reg_dt, 'MM'),'01',0)) "M01"
            , count(decode(to_char(reg_dt, 'MM'),'02',0)) "M02"
            , count(decode(to_char(reg_dt, 'MM'),'03',0)) "M03"
            , count(decode(to_char(reg_dt, 'MM'),'04',0)) "M04"
            , count(decode(to_char(reg_dt, 'MM'),'05',0)) "M05"
            , count(decode(to_char(reg_dt, 'MM'),'06',0)) "M06"
            , count(decode(to_char(reg_dt, 'MM'),'07',0)) "M07"
            , count(decode(to_char(reg_dt, 'MM'),'08',0)) "M08"
            , count(decode(to_char(reg_dt, 'MM'),'09',0)) "M09"
            , count(decode(to_char(reg_dt, 'MM'),'10',0)) "M10"
            , count(decode(to_char(reg_dt, 'MM'),'11',0)) "M11"
            , count(decode(to_char(reg_dt, 'MM'),'12',0)) "M12" 
        </when>
        <when test="selectType == 'quarter'"> /*  DECODE 함수를 활용해서 분기별로 필드를 추출한다 */
            , count(decode(to_char(reg_dt, 'MM'),'01',0)) + count(decode(to_char(reg_dt, 'MM'),'02',0)) + count(decode(to_char(reg_dt, 'MM'),'03',0)) "Q1"
            , count(decode(to_char(reg_dt, 'MM'),'04',0)) + count(decode(to_char(reg_dt, 'MM'),'05',0)) + count(decode(to_char(reg_dt, 'MM'),'06',0)) "Q2"
            , count(decode(to_char(reg_dt, 'MM'),'07',0)) + count(decode(to_char(reg_dt, 'MM'),'08',0)) + count(decode(to_char(reg_dt, 'MM'),'09',0)) "Q3"
            , count(decode(to_char(reg_dt, 'MM'),'10',0)) + count(decode(to_char(reg_dt, 'MM'),'11',0)) + count(decode(to_char(reg_dt, 'MM'),'12',0)) "Q4"
        </when>
        <when test="selectType == 'recentYear'"> /*  DECODE 함수를 활용해서 년별로 필드를 추출한다 */
            , count(decode(to_char(reg_dt, 'YYYY'),to_char(to_char(sysdate,'YYYY')-3),0)) "currentYear03"
            , count(decode(to_char(reg_dt, 'YYYY'),to_char(to_char(sysdate,'YYYY')-2),0)) "currentYear02"
            , count(decode(to_char(reg_dt, 'YYYY'),to_char(to_char(sysdate,'YYYY')-1),0)) "currentYear01"
            , count(decode(to_char(reg_dt, 'YYYY'),to_char(sysdate,'YYYY'),0)) "currentYear"
        </when>
   </choose> 
   /* DECODE 함수를 활용해서 전체합계 추출한다 */
   , count(mb_tpcd) total 
    FROM  
    (
        SELECT  
            reg_dt,
            MB_TPCD
        FROM MB_MST
        WHERE SUBSTR(reg_dt,1,4)  = #{selectYear}                
    ) MBM
    GROUP BY ROLLUP(MB_TPCD) /* 합계 및 소계를 나타낼수 있는 함수 */
</select>

 

 

이렇게 회원 월별 분기별 년도별을 알아보았습니다

조금은 어려울 수 있지만

작은 쿼리를 만들어서 테이블을 생성해서 하나씩 만들어보는 것도 좋을 듯합니다

그럼 오늘도 공부 열심히 하시고!

다음 포스팅도 많은 기대부탁드립니다~

 

728x90
반응형
728x90
반응형

CASE, GROUP BY 활용

 

'HP'라는 제품은 너무 많은 등급을 가지고 있어 제품별로 분석하기를 원하고,

'LD'라는 제품은 등급의 수가 적고 중요하므로 등급별로 분석하기를 원하며,

'PP'라는 제품은 다양한 등급을 가지고 있으나 'P530C'라는 등급은 전략적으로 관리하고자 하여 등급별로 분석하고,

나머지는 기타로 모아주기를 원한다고 생각하자

 

이런 경우에는 CASE와 GROUP BY를 활용하여 풀어보자

 

SELECT

   CASE WHEN 제품 = ‘HP’ THEN 제품

   WHEN 제품 = ‘LD’ THEN 등급 ,

   WHEN 등급 = ‘P530C’ THEN 등급

   ELSE ’기타‘

   END

FROM 매출테이블

WHERE 매출일자 LIKE ’9808%’

GROUP BY CASE WHEN 제품 = ‘HP’ THEN 제품

                                  WHEN 제품 = ‘LD’ THEN 등급 ,

                                  WHEN 등급 = ‘P530C’ THEN 등급

ELSE '기타'

END

 

 

SALE_HIST 테이블을 참조하여 ‘PENCIL’ 총 판매금액과 01번 사업장의 총판매금액과

ERASER를 판매하고 있는 사업장의 총판매 금액을 출력하고 그 나머지를 기타로 묶어 총 판매금액을 출력하시오

SELECT

   CASE WHEN SALE_ITEM = 'PENCIL' THEN SALE_ITEM

   WHEN SALE_ITEM = 'ERASER' THEN SALE_SITE

   WHEN SALE_SITE = 01 THEN SALE_SITE

   ELSE '기타'

   END AS 특별관리항목,

   SUM(SALE_AMT) AS 총판매금액

FROM SALE_HIST

GROUP BY CASE WHEN SALE_ITEM = 'PENCIL' THEN SALE_ITEM

                                  WHEN SALE_ITEM = 'ERASER' THEN SALE_SITE

                                  WHEN SALE_SITE = 01 THEN SALE_SITE

ELSE '기타'

END

 

 

TEST100 테이블을 참조하여 C2에 해당하는 값의 비율을 구하여라

SELECT C1, C2

,ROUND(RATIO_TO_REPORT(C2) OVER(),2) * 100 AS PER

FROM TEST100

 

 

TEST35 테이블을 참조하여 KEY1은 부서라고 생각하고 KEY2의 A는 판매액 B는 매입액이라고 할 때

부서별 판매액과 매입액의 차에대한 값(수익)을 구하고 차액의 비율을 구하시오

SELECT

CASE WHEN KEY1 IS NOT NULL THEN KEY1 ELSE '합계' END AS KEY1

   , SUM(CASE WHEN KEY2 = 'A' THEN AMT ELSE 0 END) AS 판매액

   , SUM(CASE WHEN KEY2 = 'B' THEN AMT ELSE 0 END) AS 매입액

   , SUM(CASE WHEN KEY2 = 'A' THEN AMT ELSE - AMT END) AS 수익

   , ROUND(SUM(CASE WHEN KEY2='A' THEN AMT ELSE -AMT END)/ SUM(CASE WHEN KEY2='A' THEN AMT END)*100 )AS PER

FROM (SELECT KEY1, KEY2, SUM(AMT) AMT

               FROM TEST35

               GROUP BY ROLLUP(KEY1), KEY2

)

GROUP BY CASE WHEN KEY1 IS NOT NULL THEN KEY1 ELSE '합계' END

ORDER BY KEY1

728x90
반응형
728x90
반응형

밑의 문제들은 SQL전문가 가이드 실습용 테이블을 활용하여 문제를 풀었다

 

SQL 전문가 가이드 실습용테이블.zip
1.03MB

 

GROUP BY, HAVING BY, WHERE 절 기본 개념은 아래의 페이지를 참조하자 

https://tantangerine.tistory.com/15

 

Oracle GROUP BY & HAVING 절 특징

GROUP BY 절 특징 GROUP BY 절을 통해 소그룹별 기준을 정한 후, SELECT절에 집계함수를 사용. 집계함수의 통계정보는 NULL 값을 가진 행을 제외하고 수행한다. GROUP BY 절에서는 ALIAS 명을 사용할 수 없다. 집..

tantangerine.tistory.com

답은 흰색으로 처리하였습니다

 

1. 포지션별 인원수, 최대키, 최소키, 평균키를 출력하시오 이때 소수점 2번째 자리까지 구하시오

SELECT POSITION 포지션, COUNT(*) 인원수, COUNT(HEIGHT) 키대상,

MAX(HEIGHT) 최대키, MIN(HEIGHT) 최소키, ROUND(AVG(HEIGHT),2) 평균키

FROM PLAYER GROUP BY POSITION

 

 

2. K-리그 선수들의 포지션별 평균키를 구하는데, 평균키가 180 센티미터 이상인 정보만 출력하시오

SELECT POSITION 포지션, ROUND(AVG(HEIGHT),2) 평균키

FROM PLAYER GROUP BY POSITION HAVING AVG(HEIGHT) >= 180;

 

 

3. K-리그의 선수들 중 삼성블루윙즈(K02)와 FC서울(K09)의 인원수를 출력하시오.

단, 가장 효율적인 자원 활용을 생각하시오

 

SELECT TEAM_ID 팀ID, COUNT(*) 인원수

FROM PLAYER

WHERE TEAM_ID IN ('K09', 'K02')

GROUP BY TEAM_ID;

 

SELECT TEAM_ID 팀ID, COUNT(*) 인원수

FROM PLAYER

GROUP BY TEAM_ID

HAVING TEAM_ID IN ('K09', 'K02');

 

 

4. 포지션별 평균 키만 출력하는데, 최대키가 190cm 이상인 선수를 포함하고 있는 포지션의 정보만 출력한다.

SELECT POSITION 포지션, ROUND(AVG(HEIGHT),2) 평균키

FROM PLAYER GROUP BY POSITION HAVING MAX(HEIGHT) >= 190;

 

728x90
반응형
728x90
반응형

GROUP BY 절 특징

 

  • GROUP BY 절을 통해 소그룹별 기준을 정한 후, SELECT절에 집계함수를 사용.
  • 집계함수의 통계정보는 NULL 값을 가진 행을 제외하고 수행한다.
  • GROUP BY 절에서는 ALIAS 명을 사용할 수 없다.
  • 집계함수는 WHERE 절에 올 수 없다.
  • 집계함수를 사용할 수 있는 GROUP BY 절보다 WHERE 이 먼저 수행된다.
  • WHERE 절은 전체 데이터를 GROUP으로 나누기 전에 행들을 미리 제거시킨다.
  • HAVING 절은 GROUP BY 절의 기준 항목이나 소그룹의 집계 함수를 이용한 조건을 표시 할 수있다.
  • GROUP BY 절에 의한 소그룹별로 만들어진 집계 데이터 중HAVING 에서 제한 조건을 두어 조건을 만족하는 내용만 출력.

HAVING 절 특징

 

  • HAVING 절은 WHERE 절과 비슷하지만 그룹을 나타내는 결과 집합의 행에 조건이 적용된다는 점에서 차이가 있다
  • HAVING 절과 GROUP 절의 순서를 바꾸어서 수행하더라도 문법 에러는 없다. 하지만 논리적으로 순서를 지키는 것을 권고
  • HAVING 절은 SELECT 절에서 사용되지 않은 칼럼이나 집계함수가 아니더라도 소그룹 집계함수를 이용한 조건을 표시을 가능

 


 

데이터의 효율적인 자원 활용 (WHERE 절과 HAVING 절의 관계)

 

  • GROUP BY 연산 전 WHERE 절에서 조건을 적용하여 필요한 데이터만 추출하여 GROUP BY 연산하는 방법
  • GROUP BY 연산 후 HAVING 절에서 필요한 데이터만 필터링하는 방법
  • 위의 두 가지 방법 중 WHERE 절에서 조건절을 적용하여 GROUP BY의 계산 대상을 줄이는 것이 효율적인 자원 사용이다

 


SELECT 문장 실행 순서

 

  1. 발췌대상 테이블을 참조한다 (FROM)
  2. 발췌대상 데이터가 아닌 것은 제거한다. (WHERE)
  3. 행들을 소그룹화 한다 (GROUP BY)
  4. 그룹핑된 값의 조건에 맞는 것만을 출력한다 (HAVING)
  5. 데이터 값을 출력/계산한다 (SELECT)
  6. 데이터를 정렬한다 (ORDER BY)

 

728x90
반응형

+ Recent posts

Powered by Tistory, Designed by wallel