2013-10-03 5 views
1

그래서 각 유형의 활동에 대해 가장 많은 점수를 가진 사용자를 표시하는 쿼리를 작성하려고합니다. 아래 테이블을 보면 알 수 있습니다. 각 액티비티는 activity_typeid이고 각각 ​​액티비티는 activity_weight입니다.같은 쿼리에서 SUM과 DISTINCT를 사용합니다.

아래 예에서 Bob은 전화 50 점, 회의 100 점을 기록했습니다. James는 콜 100 점, 회의 100 점을 기록했습니다. 통화에 대한

  1. 탑 퍼포머 = 제임스
  2. 회의 = 밥, 제임스
  3. 최고의 출연자 :

    userid  activity_typeid  activity_weight 
    ------------------------------------------------------------ 
    123 (Bob) 8765 (calls)    50 
    123 (Bob) 8121 (meetings)    100 
    431 (James) 8765 (calls)    50 
    431 (James) 8121 (meetings)   100 
    431 (James) 8765 (calls)    50 
    

    나는 다음과 같은 출력을 수 있어야합니다.

나는 모르는activity_typeid의 사전에, 그들은 무작위로 입력, 그래서 각 DISTINCT/UNIQUE의 합계를 계산 쿼리의 일종을 구축 할 수있는 경우 궁금 해서요로 activity_typeid?

미리 감사드립니다.

+0

왜 (James) (콜)이 당신의 테이블에 복제 되었습니까? – user4035

+0

죄송합니다. 더 잘 설명해야합니다. 이 작업 (호출)이 수행 될 때마다이 테이블에 새 항목이 입력됩니다. 따라서 총 50 점이 추가됩니다. 그래서 그것은 말에 대해 중복되지 않습니다. – user2656127

+0

제임스는 통화 = 50 + 50에 대해 100 포인트를 받았습니다. – user4035

답변

2

필요한 것은 분석 함수 DENSE_RANK()과 같습니다.각 활동

SELECT a.activity_typeid, GROUP_CONCAT(a.userid) userid 
    FROM 
(
    SELECT activity_typeid, userid, SUM(activity_weight) activity_weight 
    FROM table1 
    -- WHERE ... 
    GROUP BY userid, activity_typeid 
) a JOIN 
(
    SELECT activity_typeid, MAX(activity_weight) activity_weight 
    FROM 
    (
    SELECT activity_typeid, userid, SUM(activity_weight) activity_weight 
     FROM table1 
     -- WHERE ... 
    GROUP BY userid, activity_typeid 
) q 
    GROUP BY activity_typeid 
) b 
    ON a.activity_typeid = b.activity_typeid 
    AND a.activity_weight = b.activity_weight 
GROUP BY activity_typeid 

을 위해 MySQL은 DENSE_RANK() 세션 변수

을 활용하는 것입니다 모방하는 또 다른 방법은 최고 실적을해야하는 경우 한 가지 방법은 그것을에서 할
SELECT activity_typeid, GROUP_CONCAT(userid) userid 
    FROM 
(
    SELECT activity_typeid, userid, activity_weight, 
     @n := IF(@g = activity_typeid, IF(@v = activity_weight, @n, @n + 1) , 1) rank, 
     @g := activity_typeid, @v := activity_weight 
    FROM 
    (
    SELECT activity_typeid, userid, 
      SUM(activity_weight) activity_weight 
     FROM table1 
    -- WHERE ... 
    GROUP BY activity_typeid, userid 
) q CROSS JOIN (SELECT @n := 0, @g := NULL, @v := NULL) i 
    ORDER BY activity_typeid, activity_weight DESC, userid 
) q 
WHERE rank = 1 
GROUP BY activity_typeid 

출력 : 여기에

 
| ACTIVITY_TYPEID | USERID | 
|-----------------|---------| 
|   8121 | 123,431 | 
|   8765 |  431 | 

은 (는) SQLFiddle 두 검색어에 대한 데모입니다.

+0

감사합니다! 위대한 작품 : D – user2656127

+0

WHERE 절을 추가하려면 a, b 및 c 또는 끝에 한 번만 추가해야합니까? – user2656127

+0

@ user2656127 매우 환영합니다 :) 업데이트 된 답변보기. 두 WHERE 절이 같아지기를 원합니다. – peterm

0

각 사용자 및 각 활동 유형 ID의 합계를 계산하려면 GROUP BY 문을 사용해야합니다. 다음과 같이 시도하십시오.

SELECT userid, activity_typeid, SUM(activity_weight) 
FROM table 
GROUP BY userid, activity_typeid 

그런 다음 이것을 하위 쿼리로 사용하여 각 activity_typeid의 최고 수행자를 결정하십시오.

+0

그래, 하위 쿼리는 내가 약간의 도움이 필요한 것입니다. 어떤 팁? 감사! – user2656127

+0

이것 좀보세요 : http://stackoverflow.com/questions/12113699/get-top-n-records-for-each-group-of-grouped-results – Dan

+0

아,이 일은 내가해야 할 일처럼 보입니다. 감사합니다. 너 너무 많이! – user2656127

0

집계 함수를 사용하려면 DISTINCT 대신 GROUP BY을 사용해야합니다. 그룹을 useridactivity_typeid으로 지정하고 SUM(activity_weight)을 선택합니다.

SELECT userid, activity_typeid, SUM(activity_weight) 
FROM ? 
WHERE activity_typeid = ? 
GROUP BY userid 
ORDER BY SUM(activity_weight) DESC 
LIMIT 1 

당신은 출력 상단에 LIMIT을 변경할 수 있습니다 주어진 활동의 (단일)의 MVP를 선택

SELECT t.userid, t.activity_typeid, sum(t.activity_weight) 
FROM YOURTABLE t 
GROUP BY t.userid, t.activity_typeid 
0

는 물론, 그냥이 등으로 그룹을 사용 5 명 또는 10 명의 연주자를 선택하고 코드에서 그들을 검사하여 어떤 사람에게 보여주고 싶은지 확인하십시오 (예 : 두 명에게 동일한 점수가있는 경우).

0

검색어 :

+0

감사합니다. 문제는 입니다 where activity_typeid =? 그게 내가 모르는 때문에, 어떻게 해결 해야할지 모르겠다, 그리고 그 테이블 (모든 ID가 일치하는 곳)에있는 모든 ID를 반복하고 싶습니다. – user2656127

+0

당신은 런타임에 쿼리를 빌드 할 수 있다는 것을 알고 있습니다. 당신이'activity_typeid'을 안다면? 매우 쉽게 수행 할 수있는 방법을 보려면 "매개 변수가있는 쿼리"를 참조하십시오. –

+0

내가 필요로하는 것, 감사합니다 소리가 난다! – user2656127

관련 문제