서로 다른 테이블의 컬럼을 비교한 후, 둘이 같은 값인 경우 특정 컬럼의 값을 변경하기 0 2 5,919

by TigerStone [SQL Query] Oracle [2017.05.09 18:51:18]


안녕하십니까!'

MySQL(MARIADB)를 사용하고 있는데, '서로 다른 테이블의 컬럼을 비교한 후, 둘이 같은 값인 경우 특정 컬럼의 값을 변경하기'를 어떻게 구현해야할지 막막하여 질문을 드립니다.

아래 내용에서 파랗게 하이라이트한 부분에 대해 답변을 해주신다면 정말 감사하겠습니다!

 

YESTERDAY_TABLE

어제(2017-05-08) 접속한 각각의 고객(IP)들이 조회한 게시물들에서 가장 높은 비율을 보인 카테고리를 보여주고, 해당 카테고리의 게시물을 몇번 조회하였는지 카운트를 보여줍니다.

(ORDER BY 비율 DESC, 카운트 DESC)

IP 날짜 최고카테고리 비율 카운트
1 2017-05-08 A 80 8
2 2017-05-08 B 70 7
3 2017-05-08 D 60 6
... ... ... ... ...

 

TODAY_TABLE

오늘(2017-05-09) 접속한 각각의 고객(IP)들이 조회한 게시물들에서 가장 높은 비율을 보인 카테고리를 보여주고, 해당 카테고리의 게시물을 몇번 조회하였는지 카운트를 보여줍니다.

(ORDER BY 비율 DESC, 카운트 DESC)

IP 날짜 최고카테고리 비율 카운트
1 2017-05-09 A 90 9
2 2017-05-09 C 70 14
4 2017-05-09 E 70 7
... ... ... ... ...

 

TOP5_TABLE

TOP5_TABLE은 ORDER BY 비율 DESC, 카운트 DESC, 유지기간 DESC, 최근접속일 ASC로 정렬됩니다.

만일, 해당 IP의 YESTERDAY_TABLE에서의 최고카테고리와 TODAY_TABLE에서의 최고카테고리가 같으면, (IF YESTERDAY_TABLE.최고카테고리 = TODAY_TABLE.최고카테고리)

TOP5_TABLE의 유지기간에 +1을 더합니다. 즉 유지기간은 최고카테고리를 동일하게 유지한 일수입니다.

해당 IP의 YESTERDAY_TABLE에서의 최고카테고리와 TODAY_TABLE에서의 최고카테고리가 다르면, (ELSE) 유지기간을 1로 갱신합니다.

해당 IP가 YESTERDAY_TABLE에 없으면 유지기간을 1로 초기화합니다.

만일, TOP5_TABLE의 IP가 TODAY_TABLE에 존재하지 않는다면, 최근접속일에 +1을 더합니다.

IP 최고카테고리 비율 카운트 유지기간 최근접속일 (N일 전)
1 A 90 9 2 0
2 C 70 14 1 0
4 E 70 7 1 0
3 D 60 6 1 1
           

 

그리고 데이터를 2017-05-08_TABLE, 2017_05_09_TABLE과 같은 식으로, 자동적으로 테이블의 이름을 오늘 날짜로 하여, 하루치 데이터를 개별적으로 저장하고 싶습니다.

질문이 다소 많은 것 같습니다.. 정말 죄송합니다.

답변을 간절히 기다리고 있겠습니다! 

by TigerStone [2017.05.10 06:19:40]
INSERT INTO TOPK_COUNTRY_TABLE(IP, COUNTRY, RATIO, COUNT, DURATION, RECENT_ACCESS)
SELECT IP, COUNTRY, RATIO, COUNT, 0, 0
FROM(
SELECT IP, COUNTRY, RATIO, COUNT, ROW_NUMBER() OVER (ORDER BY RATIO DESC, COUNT DESC) RANK FROM TD_TOP_COUNTRY_TABLE)
WHERE RANK <= 10;

UPDATE D2_TOP_COUNTRY_TABLE SET DURATION =
CASE
WHEN YD_COUNTRY != TD_COUNTRY THEN 1
WHEN YD_COUNTRY = TD_COUNTRY THEN TD_DURATION+1 END
FROM(
    SELECT YD.COUNTRY AS YD_COUNTRY, TD.COUNTRY AS TD_COUNTRY, TD.DURATION AS TD_DURATION
    FROM YD_TOP_COUNTRY_TABLE YD, TOPK_COUNTRY_TABLE TD
    WHERE YD.IP = TD.IP
);

UPDATE D2_TOP_COUNTRY_TABLE SET RECENT_ACCESS =
CASE
WHEN YD.IP NOT IN (TD.IP) THEN TD.RECENT_ACCESS+1 END
FROM(
    SELECT YD.IP, TD.IP
    FROM YD_TOP_COUNTRY_TABLE YD, TOPK_COUNTRY_TABLE TD
);

글 작성자입니다. 이런 식으로 접근하려 했는데 UPDATE 문의 맨 첫줄에서 "ORA-00933: SQL 명령어가 올바르게 종료되지 않았습니다."라는 오류가 나면서 실행이 되지 않습니다.

도통 어떻게 접근해야할지 감이 오질 않습니다 ㅠㅠ 


by 마농 [2017.05.10 09:26:32]

실제 발생되는 데이터와, 조회하고자 하는 데이터가 있는데요.
조회하고자 하는 형태별로 테이블을 각각 다 만드시는 듯 하네요?
이렇게 하시면 테이블만 많아지고 관리 포인트만 늘어나며
데이터 일관성도 무너지게 됩니다.
테이블은 실제 발생되는 데이터만 유지하시면 됩니다.
조회하고자 하는 자료는 쿼리로 만들어 내시는게 좋을 듯 합니다.
어제테이블, 오늘테이블, 날짜별 테이블 따로 따로 가는게 이상하네요.
이러면 날짜별 테이블을 만들기 전에 어제테이블과 오늘테이블에 대한 갱신작업이 선행되어야 겠네요.
TOP 10 테이블 하나로 통합하시고 날짜 컬럼을 맨 앞쪽에 추가하시는게 좋겠네요.


문법도 많이 틀렸네요.
mysql 문법이 아니라 오라클 문법인것 같으면서도 전혀 맞질 않네요.
mysql 은 분석함수(row_number)는 지원 안합니다. LIMIT 기능을 이용하세요.
인라인뷰 사용시엔 인라인뷰에 대한 알리아스 지정 필수입니다.

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