2010-07-05 5 views
1

사용자 테이블 (사용자)과 튜토리얼 테이블 (텍스트, 비디오 및 기타)이 있습니다.다른 테이블의 집계 된 열을 그룹화하는 방법은 무엇입니까?

각 자습서에는 rating_positiverating_negative 열이 있으며 사용자 (ID)에 연결되어 있습니다.

자습서가 가장 많은 10 명의 사용자를 선택하고 자습서의 긍정적/부정적 등급이 인 것을 선택하고 싶습니다.

다음 쿼리를 시도했지만 작동하지 않습니다. tutorials_count/pos/neg에 너무 많은 결과를 반환합니다. 어떻게 올바르게 할 수 있습니까?

SELECT 
    u.id AS user_id, 
    (COUNT(t.id) + COUNT(v.id) + COUNT(o.id)) AS tutorials_count, 
    (SUM(t.rating_positive) + SUM(v.rating_positive) + SUM(o.rating_positive)) AS pos, 
    (SUM(t.rating_negative) + SUM(v.rating_negative) + SUM(o.rating_negative)) AS neg 
FROM 
    user u LEFT JOIN trick t ON u.id = t.submitter_id 
    LEFT JOIN video v ON u.id = v.submitter_id 
    LEFT JOIN other o ON u.id = o.submitter_id 
GROUP BY u.id 
ORDER BY tutorials_count DESC 
LIMIT 10 

답변

2

노동 조합에 관심있는 세 개의 테이블을 모두 하위 쿼리를 만드는 시도하고 그와 함께 가입 : 괜찮

SELECT 
    u.id AS user_id, 
    COUNT(submitter_id) AS tutorials_count, 
    IFNULL(SUM(rating_positive), 0) AS pos, 
    IFNULL(SUM(rating_negative), 0) AS neg 
FROM user u 
LEFT JOIN (
    SELECT submitter_id, rating_positive, rating_negative FROM trick 
    UNION ALL 
    SELECT submitter_id, rating_positive, rating_negative FROM video 
    UNION ALL 
    SELECT submitter_id, rating_positive, rating_negative FROM other 
) T1 
ON u.id = T1.submitter_id 
GROUP BY u.id 
ORDER BY tutorials_count DESC 
LIMIT 10 
+0

: IFNULL이 허용 대안이지만, 이식 너무 가능성이없는 MySQL의 특정있어 -

당신은 일을 수학 0으로 이러한 변환 유착을 사용해야합니다. :-) 빠른 성능으로 더 나은 쿼리가 있습니까? – Smock

1

좌파 조인, 그리고 세 가지를 모두 unioning보다 더 나은 수행합니다 집계를 수행하기 전에 테이블.

LEFT JOIN의 SUMmation은 결과가 NULL 일 수 있으며 다른 열의 합계와 함께 추가 할 수 없다는 것을 의미합니다. IE : SUM(t.rating_positive) 더 지원 기록이없는 경우 NULL + 1은 NULL 동일하기 때문에

... SUM(t.rating_positive) + 1 

는 ..., NULL 반환합니다. 이 작품

SELECT u.id AS user_id, 
      COALESCE(COUNT(t.id), 0) + COALESCE(COUNT(v.id), 0) + COALESCE(COUNT(o.id), 0) AS tutorials_count, 
      COALESCE(SUM(t.rating_positive), 0) + COALESCE(SUM(v.rating_positive), 0) + COALESCE(SUM(o.rating_positive), 0) AS pos, 
      COALESCE(SUM(t.rating_negative), 0) + COALESCE(SUM(v.rating_negative), 0) + COALESCE(SUM(o.rating_negative), 0) AS neg 
    FROM USER u 
LEFT JOIN trick t ON u.id = t.submitter_id 
LEFT JOIN video v ON u.id = v.submitter_id 
LEFT JOIN other o ON u.id = o.submitter_id 
GROUP BY u.id 
ORDER BY tutorials_count DESC 
    LIMIT 10 
+0

이것은 COALESCE가없는 경우와 동일한 (잘못된) 값을 반환합니다. – Smock

+0

이 버전과 UNION 버전은 동일합니다. UNION은 테이블 단위로 NULL을 포착하지 않아도되므로 가능한 유일한 가능성은 쿼리를 간소화 한 것입니다 세부 사항 & 내가 제공 한 쿼리로는이를 조정할 수 없습니다. –

관련 문제