SQL 사용자 Tip & 강좌
이번엔 제목에도 한번 언급했듯이 그닥 재미있는 요소의 퀴즈는 아닙니다.
그럼..
SELECT * INTO TEST_GROUP
FROM (
SELECT 10 DepthNo, 7782 EmpNo, 'CLARK' EName, 2450 Sal UNION ALL
SELECT 10, 7839, 'KING', 5000 UNION ALL
SELECT 10, 7934, 'MILLER', 1300 UNION ALL
SELECT 20, 7369,'SMITH', 800 UNION ALL
SELECT 20, 7566, 'JONES', 2975 UNION ALL
SELECT 20, 7788, 'SCOTT', 3000 UNION ALL
SELECT 20, 7876, 'ADAMS', 1100 UNION ALL
SELECT 20, 7902, 'FORD', 3000 UNION ALL
SELECT 30, 7499, 'ALLEN', 1600 UNION ALL
SELECT 30, 7521, 'WARD', 1250 UNION ALL
SELECT 30, 7654, 'MARTIN', 1250 UNION ALL
SELECT 30, 7698, 'BLAKE', 2850 UNION ALL
SELECT 30, 7844, 'TURNER', 1500 UNION ALL
SELECT 30, 7900, 'JAMES', 950
) A
위의 쿼리를 실행하여 TEST_GROUP 테이블을 생성해 봅니다.
그림 1.jpg 와 같은 데이타를 그림 2.jpg와 같이 표현을 해주시면 됩니다.
조건 :
1. TEST_GROUP 테이블 딱 한번의 스캔
2. 카티션(JOIN 포함)및 분석함수 사용불가
안녕하세요.
제가 의도한 방향과는 좀 다르긴 하지만..엘리엘님의 UNPIVOT 연산자를 이용한 방법도 있었네요~^^
sql2005에 추가된 것은 알고 있었지만, 써보지를 않아서 맞게 썼는지 몰겠네요.^^;
SELECT CASE WHEN LEFT(Grp,1) IN ('D','E') THEN '' ELSE DepthNo END as DepthNo
, EmpNo
, Ename
, CASE WHEN LEFT(Grp,1) IN ('B','D') THEN SalSum ELSE SalAvg END as Sal
FROM (
SELECT Grp
, MAX(CONVERT(VARCHAR,DepthNo)) as DepthSort
, MAX(CONVERT(VARCHAR,DepthNo)) as DepthNo
, MIN(CASE WHEN Grp = 'A' THEN CONVERT(VARCHAR,EmpNo) ELSE '' END) as EmpNo
, MIN (CASE WHEN Grp = 'A' THEN Ename ELSE SUBSTRING(Grp,2,4) END) as Ename
, SUM(Sal) SalSum, ROUND(AVG(CONVERT(FLOAT,Sal)),2) SalAvg
FROM (
SELECT DepthNo, EmpNo, Ename
, Sal as A, Sal as B합계, Sal as C평균, Sal as D전체합계, Sal as E전체평균
FROM TEST_GROUP
) A UNPIVOT (Sal FOR Grp IN (A, B합계, C평균, D전체합계, E전체평균)) AS UNPVT
GROUP BY Grp, CASE WHEN Grp = 'A' THEN EmpNo
WHEN LEFT(Grp,1) IN ('B', 'C') THEN DepthNo END
) A
ORDER BY DepthSort, Grp, EmpNo;
ROLLUP을 하지 않고 단순하게 처리해봤습니다. ROLLUP으로 처리하면 좀 더 깔끔해 질듯 합니다만.ㅎㅎ
그럼...
퀴즈는 GROUP BY 절만을 이용(2000에서도실행가능)한구현이었는데 퀴즈가 그닥재미없다보니..
조건이엉망이었네요..ㅜㅜ. 죄송합니다..
아래는 여러 방법중의 하나일 뿐이며.. 두번의GROUP BY절을응용한 방법입니다..^^*
SELECT CASE WHEN Rid IN (4,6) THEN '' ELSE SortDepthNo END DepthNo
, CASE WHEN Rid = 0 THEN EmpNo ELSE '' END EmpNo
, CASE WHEN Rid IN (4,6) THEN '전체' ELSE '' END +
CASE WHEN Rid IN (1,4) THEN '합계' ELSE EName END EName
, CASE WHEN Rid IN (1,4) THEN SalSum ELSE SalAvg END Sal
FROM (
SELECT MAX(DepthNo) SortDepthNo
, MIN(EmpNo) EmpNo
, MIN(EName) EName
, MIN(SalAvg) SalAvg
, SUM(Sal) SalSum
, CASE WHEN Rid IN (2,4) THEN Rid+2 ELSE Rid END Rid
FROM (
SELECT ISNULL(CONVERT(VARCHAR,DepthNo),'9999') DepthNo
, ISNULL(CONVERT(VARCHAR,EmpNo),'9999') EmpNo
, ISNULL(EName,'평균') EName
, SUM(Sal) Sal
, ROUND(AVG(CONVERT(FLOAT,Sal)),2) SalAvg
, GROUPING(DepthNo) + GROUPING(EmpNo) + GROUPING(EName) + GROUPING(Sal) Rid
FROM TEST_GROUP
GROUP BY DepthNo, EmpNo, EName, Sal WITH ROLLUP
) A
GROUP BY CASE WHEN Rid IN (2,4) THEN Rid+2 ELSE Rid END
, CASE WHEN Rid = 0 THEN EmpNo
WHEN Rid IN (1,3) THEN DepthNo END
) A
ORDER BY SortDepthNo, Rid, EmpNo;
본 퀴즈는 성능퍼포먼스 관점이 아닌 구현에 대한 여러가지 방법들을 같이 해봤으면 해서
내보았구요~ 앞으로도 가끔씩 잼있는 퀴즈 물고 오도록 하겠습니다..^^
참~ 예전에 가위바위보 퀴즈 올린지 꽤되었는데.. 그 당시 만들어 놓고 가끔씩 좀 더 괜찮은 아이디어가
없을까 생각은 하고 있지만.. 아직 마땅치 않네요~ 조만간 구문을 올리도록 하겠습니다.


SELECT Depthno,
Empno,
CASE
WHEN Ename = Aename THEN Ename
ELSE CASE
WHEN Ename = '합계'
AND Col = 'Sal1' THEN Ename
WHEN Ename = '합계'
AND Col = 'Avg1' THEN Aename
WHEN Ename = '전체합계'
AND Col = 'Sal1' THEN Ename
WHEN Ename = '전체합계'
AND Col = 'Avg1' THEN Aename
END
END AS [Ename],
Val
FROM (SELECT CASE
WHEN Depthno IS NULL THEN CONVERT(VARCHAR, '')
ELSE CONVERT(VARCHAR, Depthno)
END AS [DepthNo],
CASE
WHEN Empno IS NULL THEN CONVERT(VARCHAR, '')
ELSE CONVERT(VARCHAR, Empno)
END AS [EmpNo],
CASE
WHEN Grouping(Ename) = 1 --EName IS NULL r
THEN CASE
WHEN Grouping(Depthno) = 1 THEN '전체합계'
WHEN Grouping(Empno) = 1 THEN '합계'
END
ELSE Ename
END AS [Ename],
CASE
WHEN Grouping(Ename) = 1 --EName IS NULL r
THEN CASE
WHEN Grouping(Depthno) = 1 THEN '전체평균'
WHEN Grouping(Empno) = 1 THEN '평균'
END
ELSE Ename
END AS [aEname],
SUM(Sal) Sal1,
AVG(Sal) Avg1
FROM Test_group
GROUP BY Depthno,
Empno,
Ename WITH ROLLUP) T UNPIVOT ( Val FOR Col IN (Sal1, Avg1)) AS Upv
WHERE Ename IS NOT NULL
-- 솔직히 날 쿼리의 진수를 보여주는것 같아서 sorry~,
-- 하지만 혹시나 다른 분에게는 참고가 될지 몰라 올립니다.
-- 여전히 커리 미완성된 것임 (다른 사람을 위하여 ^^;).