테이블 비교하기 질문입니다. 1 7 1,482

by 일자코딩 [2013.11.20 15:04:18]


두개의 테이블에서 각각의 날짜 데이터를 비교하고 싶은데요..
4일날 데이터가 있고 5일날 데이터가 있으면
전일 4일 기준으로 5일에 추가된 데이터삭제된 데이터를 구하고 싶습니다.

두테이블 조인하여  NOT EXISTS 하여 구하면 될것같기도 한데..막상 나오면 먼가 이상한거 같아서 질문합니다..ㅜ
어떤식으로 하면될지요...
by 아발란체 [2013.11.20 16:01:43]
--추가 삭제 된 것, 둘 다 보려면 FULL OUTER JOIN 하면 될 것 같습니다.
--단서가 별로 없는 것 같아 참고 할 수 있느 질의를 올립니다.
SELECT
  *
FROM
  테이블1
FULL OUTER JOIN
  테이블2
ON
  테이블1.항목명 = 테이블2.항목명 --서로 1:1로 묶을 수 있는 항목명
WHERE
  (테이블1.날짜 = 4일 OR 테이블1.날짜 IS NULL)
  AND (테이블2.날짜 IN(4일, 5일) OR 테이블2.날짜 IS NULL)
  AND (테이블1.날짜 IS NULL OR 테이블2.날짜 IS NULL)

by 아발란체 [2013.11.20 16:36:41]
--혹 안 될지도 몰라서 테스트 진행을... ^^;

CREATE TABLE TEMP (
 IDX INT PRIMARY KEY NOT NULL,
 CONTENT VARCHAR(10),
 ALTDATE DATE
);

INSERT INTO TEMP VALUES(1, 'Hong', SYSDATE);
INSERT INTO TEMP VALUES(2, 'Bhak', SYSDATE);
INSERT INTO TEMP VALUES(3, 'Kim', SYSDATE);
INSERT INTO TEMP VALUES(4, 'Park', SYSDATE);

CREATE TABLE TEMP2 AS SELECT * FROM TEMP;
ALTER TABLE TEMP2 ADD CONSTRAINT PK_TEMP2_IDX PRIMARY KEY (IDX); 

INSERT INTO TEMP2 VALUES(5, 'Choi', SYSDATE + 1); 
INSERT INTO TEMP2 VALUES(6, 'Lee', SYSDATE + 1);
DELETE TEMP2 WHERE IDX = 4;
INSERT INTO TEMP2 VALUES(7, 'Song', SYSDATE - 1); --범위 외 데이타
INSERT INTO TEMP2 VALUES(8, 'Kang', SYSDATE - 1); --범위 외 데이타



SELECT * FROM
 TEMP T1
FULL OUTER JOIN 
 TEMP2 T2
ON 
 T1.IDX = T2.IDX
WHERE
 (TO_CHAR(T1.ALTDATE, 'YYYYMMDD') = '20131120' OR T1.ALTDATE IS NULL)
 AND
 (TO_CHAR(T2.ALTDATE, 'YYYYMMDD') IN('20131120', '20131121') OR T2.ALTDATE IS NULL)
 AND 
 (T1.ALTDATE IS NULL OR T2.ALTDATE IS NULL)
;

by 아발란체 [2013.11.20 16:37:34]

근데 서로 테이블이 다른가요?
같은 데이타인데 테이블명이 서로 다를 일이 드물 것 같은데..


by 아발란체 [2013.11.20 17:12:58]
위 같은 구조에서 ALTDATE 항목이 키로 잡혀 있다면
TO_CHAR(T1.ALTDATE, 'YYYYMMDD') = '20131120' 쓰시면 인덱스 풀스캔 되고요,
Tl.altdate >= TO_DATE(:YYYYMMDD, 'YYYYMMDD')
AND T1.altdate < TO_DATE(:YYYYMMDD, 'YYYYMMDD') + 1 식으로 기술 하셔야
Index Range Scan 됩니다.


by 야신 [2013.11.21 09:33:23]
두 테이블을 union all 로 묶고 lag 분석함수로 비교하면 어떨까 하는 생각도 드네요.

by 마농 [2013.11.21 10:03:06]
-- FULL OUTER JOIN --
SELECT NVL(a.pk1, b.pk1) pk1
     , a.pk1 pk1_a
     , b.pk1 pk1_b
     , DECODE(NULL, a.pk1, '삭제', b.pk1, '추가', '유지') flag
  FROM (SELECT pk1, pk2 FROM t WHERE pk2 = '20131104') a
  FULL OUTER JOIN
       (SELECT pk1, pk2 FROM t WHERE pk2 = '20131105') b
    ON a.pk1 = b.pk1
 ORDER BY NVL(a.pk1, b.pk1)
;
-- GROUP BY --
SELECT pk1
     , CASE WHEN MAX(pk2) = '20131104' THEN '삭제'
            WHEN MIN(pk2) = '20131105' THEN '추가'
            ELSE '유지' END flag
  FROM t
 WHERE pk2 IN ('20131104','20131105')
 GROUP BY pk1
 ORDER BY pk1
;

by 일자코딩 [2013.11.21 11:10:12]
와 이렇게 쉽게 되네요... ㅜㅜ 모두 감사합니다..^^
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입