쿼리 부탁드립니다. 0 11 1,860

by sql_master [SQL Query] [2010.01.16 18:50:07]


고수님들의 답변 기다립니다. ㅜ.ㅜ
다름이 아니라.

ID  DATE      AMT    DMG_DATE
11  20070131  111    20070315
11  20070228  222    20070405
11  20070331  223    20070104

이렇게 테이블이 구성되있을때

DMG_DATE를 기준으로 0315이면 이 마지막날 즉, DATE가 0331의 금액을  가져와야합니다.

결과 테이블은

ID  DATE      AMT    DMG_DATE  RESULT
11  20070131  111    20070315  223
11  20070228  222    20070405  NULL
11  20070331  223    20070104  111

이렇게 나와야 한는데
SCALQUERY로 하는 방법 말고는 방법이 없나요?
스칼라로하게 되면 똑같은 테이블 두번 SELECT하게 되서 다른방법을 찾고 있습니다.

고수님들 답변 부탁드립니다.

by 현 [2010.01.16 22:35:06]
결국 한번 더 읽긴 해야겠는데요.
잘만 하시면 큰 비효율은 없을 듯 합니다.

by 마농 [2010.01.18 09:19:16]
셀프조인 하셔야겠네요. 테이블 두번 읽는 것은 마찬가지구요.
스칼라서브쿼리로 하는 방법이 있겠고, 아우터조인을 이용하는 방법도 있습니다.

by 마농 [2010.01.18 09:56:14]
셀프조인을 하지 않고 테이블 한번만 읽어서 처리하게 억지로 한번 만들어 봤습니다.
다만, 이 방법이 조인방법보다 성능이 좋을지 나쁠지는 모르겠네요.
성능면에서 문제가 없다면 그냥 조인방법을 사용하는것이 좋을것 같습니다.

WITH t AS
(
SELECT 11 id, 20070131 dt, 111 amt, 20070315 dmg_dt FROM dual
UNION ALL SELECT 11, 20070228, 222, 20070405 FROM dual
UNION ALL SELECT 11, 20070331, 223, 20070104 FROM dual
)
SELECT id
, MIN(DECODE(lv,1,dt)) dt
, MIN(DECODE(lv,1,amt)) amt
, MIN(DECODE(lv,1,dmg_dt)) dmg_dt
, MIN(DECODE(lv,2,amt)) dmg_amt
FROM t
, (SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 2)
GROUP BY id, SUBSTR(DECODE(lv,1,dmg_dt,dt),1,6)
HAVING MIN(lv) = 1
ORDER BY id, dt
;

by 현 [2010.01.18 10:16:18]
절대로 한번만 읽고 처리 해야 한다면,
마농님 방법처럼 하면 되지만,
성능적으로는 좋은 방법은 될 수 없을 듯 합니다.
데이터 건수가 많다면
일단 부분범위 처리를 할 수 없으며,
메모리 영역도 사용하게 되겠죠...
따라서 두번 읽으시더라도 스칼라 서브쿼리로 구현하세요...

근데, 질문자는 안읽으시는데 답글만 다는듯...ㅎㅎ

by 글쓴이 [2010.01.18 12:21:15]
아. 답변 감사합니다. ㅜ.ㅜ;;
데이터건수는 100만건정도인데.. 이거 많다는건지.. 우선 5년정도에 해당하는 데이터입니다. 가장 중요한 테이블이라 달마다 데이터가 더 증가하거든요..
우선은 두번은 읽기는 읽는데 스칼라로 하지않고 from절에서 같은 테이블을 두번 썼거든요. 스칼라로 하는거랑 from절에 두번 쓰는거랑 cbc겠지만 보통 성능은 어느쪽이 더 좋은지요..?
그리고 마농님 이 말한것도 한번 해봐야겠네요.. ^^

by 마농 [2010.01.18 12:40:32]
보통, 코드성 데이터의 경우엔 스칼라가 좋습니다. 대용량의 경우엔 조인이 낫구요.
위의 경우엔 아우터조인으로 하시는것이 좋을듯 합니다.
허나, 이것은 제 의견일뿐 절대적인 것은 아닙니다.
직접 여러가지 테스트 비교 해보시고 스스로 판단하세요.

by 글쓴이 [2010.01.18 13:51:29]
마농님 답변 감사합니다..
스칼라 쿼리로 함 해봤는데요. 속도가 너무 늦네요.10초 정도? 그래서 plan 떠봤더니 스칼라 한 부부분 모두 풀스캔하고 있네요.. 가뜩이나 코드성이 아니라. 가장 중요한 테이블을 from 절과 select 절에서 돌리니 그리고 스칼라에서 pk 값을 모두 조인걸수 없는 상황입니다. 그래서 풀스캔하는거 같구요.. 이럴때는 아우터 조인을 해야하나요? 근데 이런상황에서 outer 조인은 어떤식으로 해야할까요 ?

by 현 [2010.01.18 14:29:14]
그런 경우라면 아우터 조인을 하더라도 속도가 늦을 확률이 많습니다.

여기서 덧글 달아드리는 것은 일반적인 상황에 대해서 달아 드리는 것이지
절대적인 정답이 될 수 없습니다.
이유는...그 쪽 상황을 잘 모르기 때문입니다.

눈을 모두 가려놓고 속도 문제를 운운 하는 것은 좀 무리가 있다고 생각합니다.
새로이 작성하신 쿼리, 테이블 정보, 인덱스정보, 통계정보,(트레이스정보) 등을 올려주시면 보다 정확한 조언을 구하실 수 있을 겁니다.


by 마농 [2010.01.18 15:11:17]
스칼라조인의 경우엔 전체자료중 일부만을 건건이 1대1로 찾으므로 인덱스가 필수사항입니다.
아우터조인의 경우엔 전체 대 전체로 조인하는 것이므로 해쉬조인으로 풀릴 가능성이 높습니다.
인덱스를 경유해 풀린다면 중첩조인(NL)로 풀릴 수도 있구요.
아우터 조인은 스칼라가 아닌 그냥 From절에 테이블 두번 쓰면 됩니다.

WITH t AS
(
SELECT 11 id, 20070131 dt, 111 amt, 20070315 dmg_dt FROM dual
UNION ALL SELECT 11, 20070228, 222, 20070405 FROM dual
UNION ALL SELECT 11, 20070331, 223, 20070104 FROM dual
)
SELECT a.id, a.dt, a.amt, a.dmg_dt, b.amt
FROM t a, t b
WHERE a.id = b.id(+)
AND TO_CHAR(LAST_DAY(TO_DATE(a.dmg_dt,'yyyymmdd')),'yyyymmdd') = b.dt(+)
;

by 마농 [2010.01.18 15:48:06]
[이럴때는 아우터 조인을 해야하나요?] 라고 질문하셨는데요.
해도 되는지?를 질문하시는것 보다는 일단 할수 있는 여러가지 방법을 다 해보고
각각의 성능을 비교해보라고 말하고 싶네요.

by 글쓴이 [2010.01.18 15:57:59]
모두 답변 감사합니다..
덕분에 도움이 많이 되었습니다. (-.-)(_._)
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입