2012-07-17 2 views
2

사용자가 매일 점수를 추적하는 표가 있습니다. 그것은이는 대충 다음과 같다 : 지금이다 weighted_score 선수가 선수 기록 데이터에서 매일 다시 계산하는누락 된 행의 기본값을 사용하여 mysql 조인을 수행하는 방법

CREATE TABLE `Players` (
    `player_id` INTEGER NOT NULL, 
    `weighted_score` DOUBLE NOT NULL 
); 

:

CREATE TABLE `DailyScores` (
    `player_id` INTEGER NOT NULL, 
    `day_id` INTEGER NOT NULL, 
    `score` DOUBLE NOT NULL 
); 

나는이처럼 보이는 플레이어 테이블이 있습니다. 나는이 같은 여러 패스에 뭔가를이 작업을 수행 할 수 있습니다

-- Clear out the old values 
UPDATE Players SET Players.weighted_score = 0; 

-- Then several times with different @weight and @day values 
UPDATE Players p JOIN DailyScores ds 
    ON p.player_id = ds.id 
    WHERE ds.day_id = @day 
    SET p.weighted_score = p.weighted_score + @weight * ds.score; 

이것은 플레이어가에 대한 점수 항목이하지 않는 일이있을 수있는 사건을 처리합니다.

그러나 좀 더 이렇게 될 업데이트를 다시 싶습니다

UPDATE Players p 
    JOIN DailyScores ds1 ON p.player_id = ds1.id 
    JOIN DailyScores ds2 ON p.player_id = ds2.id 
    JOIN DailyScores ds3 ON p.player_id = ds3.id 
    WHERE 
    ds1.day_id = @day1 AND 
    ds2.day_id = @day2 AND 
    ds3.day_id = @day3 
    SET p.weighted_score = @w1 * ds1.score + @w2 * ds2.score + @w3 * ds3.score; 

하지만 누락 된 점수가있는 경우이 실패 할 것이라 생각합니다. 누락 일 수를 0으로 만들 수 있습니까? 가장 좋은 방법 -

답변

1

COALESCE() 기능을 사용하십시오. NULL이 아닌 첫 번째 매개 변수를 반환합니다.

UPDATE Players p 
    LEFT JOIN DailyScores ds1 ON (p.player_id = ds1.id AND ds1.day_id = @day1) 
    LEFT JOIN DailyScores ds2 ON (p.player_id = ds2.id AND ds2.day_id = @day2) 
    LEFT JOIN DailyScores ds3 ON (p.player_id = ds3.id AND ds3.day_id = @day3) 
    SET p.weighted_score = 
    @w1 * COALESCE(ds1.score, 0) + 
    @w2 * COALESCE(ds2.score, 0) + 
    @w3 * COALESCE(ds3.score, 0); 

는 또한 플레이어가 재생되지 않았을 때 DailyScores에 대한 기록이 없을 수 있습니다 때문에 LEFT JOIN을해야한다.

+0

실제로 올바르게 작동하도록 수정되었습니다. –

1

하는

LEFT JOIN 첫 번째 문제에 대한 올바른 솔루션입니다 편집 0

DEFAULT 세트 LEFT JOIN 대신 JOIN를 사용해보십시오, 두 번째는 당신은 INSERT이 필요합니다 이 문제를 해결하려면, 그래서 INSERT ... ON DUPLICATE KEY UPDATE을 사용하는 것입니다

INSERT INTO table(cols) VALUES(values) ON DUPLICATE KEY UPDATE score=.... 
관련 문제