2013-08-25 7 views
3

테이블의 각 사용자에 대해 SUM() 가져 오려고하지만 MySQL 잘못된 값을 반환하고 있습니다. MySQL : SUM() JOIN 함께 잘못된 값을 반환합니다.

은 ( http://sqlfiddle.com/#!2/7b988/4/0)

user amount 
110  20.898319244385 
114  43.144836425781 
115  20.487638473511 
116  26.07483291626 
117  93.054000854492 

보는 방법입니다하지만이 보이게 않는 방법이다 (http://sqlfiddle.com/#!2/7b988/2/0)

user amount 
110  167.186554 
114  129.434509 
115  143.413469 
116  208.598663 
117  744.432007 

이 쿼리 내가 실행하려고하고 있습니다 :

SELECT 
    blocks.user_id, 
    SUM(payout_history.amount) as amount 
FROM blocks 
LEFT JOIN payout_history 
ON blocks.user_id = payout_history.user_id 
WHERE confirms > 520 
GROUP BY blocks.user_id 

내가 뭘 잘못하고 있니? >http://sqlfiddle.com/#!2/7b988/48



--- 편집 --- 쿼리가 작동 (또는 방법에 대한 설명이 아니라 쿼리가 작동하지 않는 이유 -

SELECT bl.user_id, SUM(ph.amount) PAIDOUT 
FROM (
    SELECT distinct blocks.user_id 
    FROM blocks 
    WHERE confirms > 520 
) bl 
LEFT JOIN payout_history ph 
ON bl.user_id = ph.user_id 
GROUP BY ph.user_id 
; 

SQLFiddle :

답변

7

이 쿼리) ----

예상되는 결과를 보면 쿼리에서 각 user_id에 대해 amount 열의 합계를 계산해야하지만 그 값은에만 해당됩니다.또한 blocks 테이블에 있으며 blocks.confirms 값이 520보다 깁니다. blocks 테이블에 동일한 user_id에 대한 많은 레코드를 포함 할 수 있으므로이 경우에는 단순 조인 (왼쪽 외부 조인)이 작동하지 않습니다. 예제는 user_id=110의 행을 반환하는 쿼리는 다음과 같은 결과 제공 : 첫 번째 joinded 테이블에서 각 레코드를 취 이런 식으로

SELECT * 
FROM blocks 
WHERE confirms > 520 
     AND user_id = 110; 

+ ------- + ------------ + ----------- + ------------- + 
| id  | user_id  | reward  | confirms  | 
+ ------- + ------------ + ----------- + ------------- + 
| 0  | 110   | 20.89832115 | 521   | 
| 65174 | 110   | 3.80357075 | 698   | 
| 65204 | 110   | 4.41933060 | 668   | 
| 65218 | 110   | 4.69059801 | 654   | 
| 65219 | 110   | 4.70222521 | 653   | 
| 65230 | 110   | 4.82805490 | 642   | 
| 65265 | 110   | 5.25058079 | 607   | 
| 65316 | 110   | 6.17262650 | 556   | 
+ ------- + ------------ + ----------- + ------------- + 

straigh 가입 (및 왼쪽/오른쪽 외부 조인) 작품을,이 쌍 다른 조인 된 테이블의 모든 행을 조인 조건을 만족시키는 상태로 기록하십시오. 왼쪽 가입 우리의 경우

는 아래의 결과 집합이 생성

SELECT * 
FROM blocks 
LEFT JOIN payout_history 
ON blocks.user_id = payout_history.user_id 
WHERE confirms > 520 
    AND blocks.user_id = 110; 
+ ------- + ------- + ----------- + -------- + --- + ------- + ----------- + 
| id  | user_id | reward  | confirms | id | user_id | amount  | 
+ ------- + ------- + ----------- + -------- + --- + ------- + ----------- + 
| 0  | 110  | 20.89832115 | 521  | 1 | 110  | 20.898319 | 
| 65174 | 110  | 3.80357075 | 698  | 1 | 110  | 20.898319 | 
| 65204 | 110  | 4.41933060 | 668  | 1 | 110  | 20.898319 | 
| 65218 | 110  | 4.69059801 | 654  | 1 | 110  | 20.898319 | 
| 65219 | 110  | 4.70222521 | 653  | 1 | 110  | 20.898319 | 
| 65230 | 110  | 4.82805490 | 642  | 1 | 110  | 20.898319 | 
| 65265 | 110  | 5.25058079 | 607  | 1 | 110  | 20.898319 | 
| 65316 | 110  | 6.17262650 | 556  | 1 | 110  | 20.898319 | 
+ ------- + ------- + ----------- + -------- + --- + ------- + ----------- + 

우리가 SUM(amount) .... GROUP BY user_id를 추가하면 지금, MySQL은 위의 결과 집합의 모든 amount 값의 합을 calucate 것 (8 행 * 20.898 = ~ 167.184)

SELECT blocks.user_id, sum(amount) 
FROM blocks 
LEFT JOIN payout_history 
ON blocks.user_id = payout_history.user_id 
WHERE confirms > 520 
    AND blocks.user_id = 110 
GROUP BY blocks.user_id; 
+ ------------ + ----------------- + 
| user_id  | sum(amount)  | 
+ ------------ + ----------------- + 
| 110   | 167.186554  | 
+ ------------ + ----------------- + 



당신이 우리에게 원하는 결과를 제공하지 않습니다에 가입이 경우시피 - 우리는 이름이 뭔가 a semi join 필요 - 세미 조인의 아래 다른 변종은, 줄 그들 시도 :

SELECT bl.user_id, SUM(ph.amount) PAIDOUT 
FROM (
    SELECT distinct blocks.user_id 
    FROM blocks 
    WHERE confirms > 520 
) bl 
LEFT JOIN payout_history ph 
ON bl.user_id = ph.user_id 
GROUP BY ph.user_id 
; 


SELECT ph.user_id, SUM(ph.amount) PAIDOUT 
FROM payout_history ph 
WHERE ph.user_id IN (
    SELECT user_id FROM blocks 
    WHERE confirms > 520 
) 
GROUP BY ph.user_id 
; 

SELECT ph.user_id, SUM(ph.amount) PAIDOUT 
FROM payout_history ph 
WHERE EXISTS (
    SELECT 1 FROM blocks bl 
    WHERE bl.user_id = ph.user_id 
     AND bl.confirms > 520 
) 
GROUP BY ph.user_id 
; 
+0

이것은 내가 후에하는 해결책 인 것 같다. 왜 작동하는지 이해할 수 있도록 설명해 주시겠습니까? – Tyler

+3

@roboreb 질문이 왜 작동하지 않는지에 대한 설명을 추가했습니다. – krokodilko

관련 문제