테이블 업데이트 하기 -ms sql 0 1 1,150

by 갈매기 [SQL Query] [2018.08.20 08:58:35]


Final- end of 8/13
ID refilled_date lastAction_date DSPSed Check
0001 20180530175138 20180810134942 2 0
0002 20180709171247 20180813214754 5 NULL
0003 20180509134831 20180727174547 1 1

 

History- end of 8/13
ID Status change_dtm check
0001 refilled 20180630175138 NULL
0001 dspsed 20180630195138 NULL
0001 dspsed 20180630205138 NULL
0001 lastAction 20180810134942 0
0002 refilled 20180709171247 NULL
0002 dspsed 20180709191247 NULL
0002 dspsed 20180710171247 NULL
0002 dspsed 20180711171247 NULL
0002 dspsed 20180713171247 NULL
0002 dspsed 20180813214754 NULL
0003 refilled 20180509134831 NULL
0003 dspsed 20180511134831 NULL
0003 lastAction 20180727174547 1

 

Dsps- end of 8/13
id dsps_dtm dsps_qty
0001 20180630195138 1
0001 20180630205138 1
0002 20180709191247 1
0002 20180710171247 1
0002 20180711171247 1
0002 20180713171247 1
0002 20180809171247 1
0003 20180511134831 1

상기와 같이 저장되어 있는 테이블이 있습니다. 3개의 테이블을 조인합니다. final table을 History테이블과 dsps를 이용하여 업데이트합니다. history 테이블과 dsps테이블은 자동으로 업데이트 됩니다. 

Final 테이블의 내역중에 refilled_date와 LastAction_date는 HIstory테이블에서 가지고 오고, dspsed 항목은 dsps항목의 수량의 합으로 가지고 옵니다. 

Final 테이블을 업데이트 하는데 조건은, 

조건1. Final 테이블의 Check 항목이 Null이고, ID별로 final 테이블의  refilled_date날짜와 history테이블의 최신 Change_dtm 같다면, 상기 테이블의 정보를 변경해야 합니다.

조건 2.History테이블의  change_dtm 이갱신되거나, ID가 새롭게 생성된다면 테이블을 업데이트 합니다. 

조건 3. Final 테이블의 check 항목에 숫자가 기입되어 있는것은 예전 것은 final table에 그냥 남겨 둡니다. 

예를 들어 

8/16일의 history 테이블과 dsps 테이블이 하기와 같다면, 

History- end of 8/16
ID Status change_dtm check
0001 refilled 20180630175138 NULL
0001 dspsed 20180630195138 NULL
0001 dspsed 20180630205138 NULL
0001 lastAction 20180810134942 0
0002 refilled 20180709171247 NULL
0002 dspsed 20180709191247 NULL
0002 dspsed 20180710171247 NULL
0002 dspsed 20180711171247 NULL
0002 dspsed 20180713171247 NULL
0002 dspsed 20180813214754 NULL
0003 refilled 20180509134831 NULL
0003 dspsed 20180511134831 NULL
0003 lastAction 20180727174547 1
0002 dspsed 20180814174547 NULL
0002 dspsed 20180815010101 NULL
0001 refilled 20180815120000 Null
0001 dspsed 20180816121111 Null
0001 lastAction 20180816230000 0
0003 refilled 20180816231211 NULL
0004 refilled 20180816231900 Null

 

Dsps- end of 8/16
id dsps_dtm dsps_qty
0001 20180630195138 1
0001 20180630205138 1
0002 20180709191247 1
0002 20180710171247 1
0002 20180711171247 1
0002 20180713171247 1
0002 20180809171247 1
0003 20180511134831 1
0002 20180814174547 1
0002 20180815010101 1
0001 20180815120000 1

 

상기와 같이 두 테이블이 업데이트 될때, 8/17일에 16일까지의 변경사항을 final 테이블에 업데이트 하고자 합니다.  제가 원하는 final 테이블의 값은 하기와 같습니다. 

Final- end of 8/15
ID refilled_date lastAction_date DSPSed Check
0001 20180530175138 20180810134942 2 0
0002 20180709171247 20180815010101 7 NULL
0001 20180815120000 20180816121111 1 0
0003 20180509134831 20180727174547 1 1
0003 20180816231211     NUll
0004 20180816231900     NULL

 

기존 history 테이블과 dsps 테이블의 데이타 량이 매일 늘어나기에 자료가 많습니다. 하여 두 테이블을 이용하여 final 테이블을 생성하여 삭제 생성을 반복하면서 업데이트 하는데, 시간이 너무 많이 걸려서, 현재는 final 테이블을 하나 만들어 놓고, 나머지 두 테이블을 이용하여 final 테이블을 업데이트 하면 시간 절약을 할 수 있지 않을까 합니다. 

 

고견 부탁 드립니다. 

감사합니다. 

by 마농 [2018.08.20 11:45:03]
MERGE INTO Final a
USING
(
SELECT a.*
  FROM (SELECT id
             , MIN(change_dtm) refilled_date
             , MAX(CASE WHEN Status != 'refilled' THEN change_dtm END) lastAction_date
             , SUM(CASE WHEN Status = 'dspsed' THEN 1 END) DSPSed
             , MIN(Checked) Checked
          FROM (SELECT ID, Status, change_dtm, Checked
                     , COUNT(CASE WHEN Status = 'refilled' THEN 1 END)
                       OVER(PARTITION BY ID ORDER BY change_dtm) grp
                  FROM History
                ) a
         GROUP BY id, grp
        ) a
  LEFT OUTER JOIN Final b
    ON a.id              = b.id
   AND a.refilled_date   = b.refilled_date
   AND ISNULL(a.lastAction_date, '') = ISNULL(b.lastAction_date, '')
   AND ISNULL(a.DSPSed         , -1) = ISNULL(b.DSPSed         , -1)
   AND ISNULL(a.Checked        , -1) = ISNULL(b.Checked        , -1)
 WHERE b.id IS NULL
) b
ON (a.id              = b.id
AND a.refilled_date   = b.refilled_date
)
WHEN MATCHED THEN
    UPDATE
	   SET a.lastAction_date = b.lastAction_date
         , a.DSPSed          = b.DSPSed
         , a.Checked         = b.Checked
WHEN NOT MATCHED THEN
    INSERT VALUES(b.id, b.refilled_date, b.lastAction_date, b.DSPSed, b.Checked)
;

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입