2013-01-25 11 views
5

私は、人々が別の場所にいる人々の投票を送信するデータベースを持っています。ある時点で、私は各地で最も多くの投票権を持つ人物を見つけたいと思います。各グループの最大行を取得する方法は?

enter image description here

は今、これらは次のとおりです。私は、この結果を与える

SELECT placeId, userVotedId, cnt 
FROM 
    (SELECT uvo.userVotedId, p.placeId, count(*) as cnt 
    FROM users as u, users_votes as uvo, places as p 
    WHERE u.userId = uvo.userVotedId 
     AND p.placeId = uvo.placeId 
    GROUP BY userVotedId, placeId) 
AS RESULT 

:(人が2つの異なる場所で投票することができます)

これは、SQLは、私がこれまで持っています私が本当に望む行:

enter image description here

私はこれを得るために私の質問に何が欠けていますか?

  • 場所ごとに1つの結果が必要です。だから私は、最も投票を受けたuserVotedIdとは別のplaceIdsしか見るべきではありません。

  • 同点の場合、ランダムな勝者が行います!

+0

同一であり、何を取得し、何をしたい: -

--edit要求されるように、ここでの最終的なコードです。だから、あなたのクエリが動作します! – cha

+0

@cha私は同じと思ったが、ダブルplaceid = 51を取り除くことがポイントである.4つの凹凸のある赤いボックスの代わりに、これを指摘するより把握しやすい方法があるかもしれない;-) – KekuSemau

+0

トップを取得しようとするならあなたの結果のplaceIDでさらにグループ化した後は、cntに基づいた行ですが、これは最初に表示されるよりも難しい問題です。 SQL Serverでは、これをAPPLYで実現できますが、これはMySQLではサポートされていません(?)。 – Matthew

答えて

3

使用すると、1件の以上の集計が必要のように思えます。あなたの cnt値と GROUP BY placeId, userVotedIdMAX()集計を使用します。

SELECT placeId, userVotedId, max(cnt) 
FROM 
(
    SELECT uvo.userVotedId, p.placeId, count(*) as cnt 
    FROM users as u 
    INNER JOIN users_votes as uvo 
    ON u.userId = uvo.userVotedId 
    INNER JOIN places as p 
    ON p.placeId = uvo.placeId 
    GROUP BY userVotedId, placeId 
) AS RESULT 
GROUP BY placeId, userVotedId 

注:私が代わりにテーブル間のコンマの JOIN構文を使用するようにクエリを変更しました。

編集は、あなたのコメントに基づいて、次の作業をする必要があります:あなたは乱数をしたい場合は、

| USERVOTEDID | PLACEID | CNT | 
------------------------------- 
|   65 |  11 | 1 | 
|   67 |  13 | 1 | 
|   67 |  25 | 1 | 
|   67 |  51 | 2 | 

編集#2:

select total.uservotedid, 
    total.placeid, 
    total.cnt 
from 
(
    SELECT uvo.userVotedId, p.placeId, count(*) as cnt 
    FROM users as u 
    INNER JOIN users_votes as uvo 
    ON u.userId = uvo.userVotedId 
    INNER JOIN places as p 
    ON p.placeId = uvo.placeId 
    GROUP BY userVotedId, placeId 
) total 
inner join 
(
    select max(cnt) Mx, placeid 
    from 
    (
    SELECT uvo.userVotedId, p.placeId, count(*) as cnt 
    FROM users as u 
    INNER JOIN users_votes as uvo 
     ON u.userId = uvo.userVotedId 
    INNER JOIN places as p 
     ON p.placeId = uvo.placeId 
    GROUP BY userVotedId, placeId 
) mx 
    group by placeid 
) src 
    on total.placeid = src.placeid 
    and total.cnt = src.mx 

が結果がSQL Fiddle with Demo

を参照してください。同値であれば返され、ユーザー変数を使用できます:

select uservotedid, 
    placeid, 
    cnt 
from 
(
    select total.uservotedid, 
    total.placeid, 
    total.cnt, 
    @rownum := case when @prev = total.placeid then @rownum+1 else 1 end rownum, 
    @prev := total.placeid pplaceid 
    from 
    (
    SELECT uvo.userVotedId, p.placeId, count(*) as cnt 
    FROM users as u 
    INNER JOIN users_votes as uvo 
     ON u.userId = uvo.userVotedId 
    INNER JOIN places as p 
     ON p.placeId = uvo.placeId 
    GROUP BY userVotedId, placeId 
) total 
    inner join 
    (
    select max(cnt) Mx, placeid 
    from 
    (
     SELECT uvo.userVotedId, p.placeId, count(*) as cnt 
     FROM users as u 
     INNER JOIN users_votes as uvo 
     ON u.userId = uvo.userVotedId 
     INNER JOIN places as p 
     ON p.placeId = uvo.placeId 
     GROUP BY userVotedId, placeId 
    ) mx 
    group by placeid 
) src 
    on total.placeid = src.placeid 
    and total.cnt = src.mx 
    order by total.placeid, total.uservotedid 
) src 
where rownum = 1 
order by placeid, uservotedid 

を簡単にするためにSQL Fiddle with Demo

+0

nope ... not working:http://imgur.com/8cpl8pO –

+0

あなたは場所によって最大を望みますか?または、ユーザーIDも必要ですか? – Taryn

+0

場所ごとに1つの結果が必要です。だから私は、最も投票を受けたuserVotedIdとは別のplaceIdsしか見るべきではありません。 –

1
SELECT placeId, userVotedId, MAX(cnt) 
    FROM (SELECT uvo.userVotedId, p.placeId, count(*) AS cnt 
      FROM users as u, users_votes as uvo, places as p 
      WHERE u.userId = uvo.userVotedId AND p.placeId = uvo.placeId 
      GROUP BY userVotedId, placeId) AS RESULT 
    GROUP BY placeId 
+0

これは1つの値を返すだけです... –

+0

@omegatai - 私はグループ化節を逃しました、答えが更新されました。 – MuhammadHani

+0

いいえ、まだ動作していません... http://imgur.com/nQ2PA2u –

1

を参照してください、私はあなたのクエリのテストと呼ばれる:

SELECT * 
FROM Test T JOIN (
SELECT t.placeId, Max(t.cnt) maxcnt 
FROM Test t 
GROUP BY t.placeId) T2 ON T.placeId = T2.placeId and T.cnt = T2.maxcnt 

ここFiddleです。

ところで - テスト=:

SELECT uvo.userVotedId, p.placeId, count(*) as cnt 
    FROM users as u 
    INNER JOIN users_votes as uvo 
    ON u.userId = uvo.userVotedId 
    INNER JOIN places as p 
    ON p.placeId = uvo.placeId 
    GROUP BY userVotedId, placeId 

幸運。

SELECT * 
FROM (SELECT uvo.userVotedId, p.placeId, count(*) AS cnt 
      FROM users as u, users_votes as uvo, places as p 
      WHERE u.userId = uvo.userVotedId AND p.placeId = uvo.placeId 
      GROUP BY userVotedId, placeId) T JOIN (
SELECT t.placeId, Max(t.cnt) maxcnt 
FROM (SELECT uvo.userVotedId, p.placeId, count(*) AS cnt 
      FROM users as u, users_votes as uvo, places as p 
      WHERE u.userId = uvo.userVotedId AND p.placeId = uvo.placeId 
      GROUP BY userVotedId, placeId) t 
GROUP BY t.placeId) T2 ON T.placeId = T2.placeId and T.cnt = T2.maxcnt 
+0

@omegatai - 私はこのデモを私のSQLと一緒に使っていました - ここでは謎です:http://sqlfiddle.com/#!2/23bd7/6 – sgeddes

+0

かなりうまくいきます。こちらをご覧ください:http://sqlfiddle.com/#!2/6a8f4/1 –