안녕하세요 처음으로 통계쿼리를 만들어보려하는 초보자입니다.
마농님과함께하는 advanced oracle sql 세미나 자료를 참고해서 힘겹게 힘겹게 쿼리를 짜보고있는데
도저히 진행이되질않아 문의드립니다
<<< code()버튼클릭하여 SQL문장 작성이되질않아 그냥복사해서 붙여넣겠습니다.
이화면에서는 복사해서가져오니 줄이엉망으로 잡히네요.. >>>
SELECT DECODE(T.FLAG, 1, T.PATNAME, NULL) PATNAME,
DECODE(T.FLAG, 1, T.IPCOUNT||'건', T.ICUIPDATE) IPCOUNT
FROM (
SELECT F.PATNAME PATNAME ,
DECODE(GROUPING(F.ICUIPDATE), 1, NULL, F.ICUIPDATE) ICUIPDATE,
DECODE(GROUPING(F.ICUIPDATE), 1, COUNT(F.IPCOUNT), NULL) IPCOUNT ,
GROUPING(F.ICUIPDATE) FLAG
FROM ( --대상환자[입실COUNT]
SELECT B.PATNAME PATNAME,
COUNT(*) IPCOUNT,
A.ICUIPDATE ICUIPDATE
FROM ( SELECT PATNO ,
PATNAME ,
FUN_ACC_LOAD_AGE(JUMINNO) AGE
FROM ACCPATINF ) B ,
--중환자실입실환자
( SELECT PATNO ,
ICUIPDATE||ICUIPTIME ICUIPDATE,
NVL(ICUTWDATE,TO_CHAR(SYSDATE,'YYYYMMDD'))||
NVL(ICUTWTIME,TO_CHAR(SYSDATE,'HH24MI')) ICUTWDATE,
STATUS
FROM CQIICUID1
WHERE ICUIPDATE BETWEEN &as_sdate AND &as_edate ) A
WHERE A.PATNO = B.PATNO
AND B.AGE >= 18 -- 18세이상
GROUP BY B.PATNAME,A.ICUIPDATE
) F
GROUP BY GROUPING SETS((F.PATNAME),(F.PATNAME,F.ICUIPDATE)) --서로다른 기준으로 합계구하기
) T
GROUP BY T.PATNAME,T.ICUIPDATE,T.IPCOUNT,T.FLAG
ORDER BY T.PATNAME ASC,T.FLAG DESC
원하는 쿼리결과는
각환자별로 입실건수 그밑에 입실일시가나와요하구요
맨마지막엔 총건수가 나와야합니다..
=====출력시 현재=====
함장근 2건
201410271800
201410301350
허남수 1건
201410021340
황금용 1건
201410192040
황태혁 1건
201410291605
=====원하는결과=====
함장근 2건
201410271800
201410301350
허남수 1건
201410021340
황금용 1건
201410192040
황태혁 1건
201410291605
총계 5건
GROUP BY ROLLUP을 사용해봤지만 위에사용한 함수부터 이해를못하고 접근했더니 원하는결과가안나오네요
group by rollup(or groupping sets)과 윈도우즈 함수를 조합하면 원하는 결과를 만들 수 있을 거 같습니다.
(다만 PATNAME는 같은 이름이 있을 수 있으므로 PATNO를 사용하세요.)
GROUP BY ROLLUP(B.PATNO,A.ICUIPDATE)
HAVING GROUPING(B.PATNO)||GROUPING(A.ICUIPDATE) IN ('00','11') 이렇게 하면
B.PATNO,A.ICUIPDATE 그룹한값과 전체로 그룹한 2개를 컨트롤 할 수 있습니다.
이름은 MAX(B.PATNAME)를 이용해서 보여주세요.
-----------------
함장근, 201410271800, 1
함장근, 201410301350, 1
...
, , 5
-----------------
이 상태에서 윈도우즈 함수를 이용해서 PATNAME의 총건수를 구하시면 될거 같습니다.
COUNT(*) OVER (PARTITION BY B.PATNO ORDER BY A.ICUIPDATE ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
그러면 아래와 같은 형식으로 값을 구할 수 있고 DECODE를 이용해서 GROUPING(B.PATNO)||GROUPING(A.ICUIPDATE) 값에 따라 건수 보여주는 값을 선택하도록 하면 될 거 같습니다.
----------------
함장근, 201410271800, 1, 2
함장근, 201410301350, 1, 2
...
, , 5, 1
-----------------
보여주는 값을 컨트롤 하는 것은 윈도우 함수를 이용해서 컨트롤이 가능합니다.
ROW_NUMBER() OVER (PARTITION BY B.PATNO ORDER BY A.ICUIPDATE) - 순번 부여해서 1번만 보여주도록
LAG(B.PATNO,1) OVER (PARTITION BY B.PATNO ORDER BY A.ICUIPDATE) 를 이용해 전 ROW의 PATNO를 가져와서 현재 ROW의 PATNO과 비교해서 같으면 안보여주게 조건 처리
SELECT DECODE(1, GROUPING(a.patno), '총계', GROUPING(a.icuipdate), b.patname) patname , DECODE(1, GROUPING(a.icuipdate), COUNT(*)||'건', a.icuipdate||a.icuiptime) ipcount FROM cqiicuid1 a , accpatinf b WHERE a.patno = b.patno AND a.icuipdate BETWEEN &as_sdate AND &as_edate AND fun_acc_load_age(b.juminno) >= 18 GROUP BY ROLLUP( (a.patno, b.patname) , (a.icuipdate, a.icuiptime) ) ORDER BY GROUPING(a.patno) , a.patno , GROUPING(a.icuipdate) DESC , a.icuipdate , a.icuiptime ;