4

解決するのが非常に簡単でなければならないことを尋ねて申し訳ありませんが、これについて頭を悩ませることはできません..私の質問に本当にふさわしいタイトルを思いつくことさえできませんでした.それについてもご容赦ください. .

各ユーザーが質問に対して複数の回答を投稿し、他のユーザーがこれらの回答に投票できる投票があります。すべてのユーザーの最も投票数の多い回答が返される結果を取得する必要があります。

テスト ケース: 「あなたの最も好きな歌の引用は?」のような質問を想定してみましょう。

CREATE TABLE `answers` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`authorId` INT,
`answer` TEXT NOT NULL ,
`votes` INT NOT NULL 
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO `answers` VALUES
(1, 30, "The West is the Best", 120),
(2, 30, "Come on, baby, light my fire", 100),
(3, 31, "Everything's gonna be allright", 350),
(4, 31, "Sayin' oooh, I love you", 350),
(5, 31, "Singing sweet songs of melodies pure and true", 290),
(6, 32, "I'm your pole and all you're wearing is your shoes", 540),
(7, 32, "And I'm crazier when I'm next to her", 180),
(8, 32, "You hear the music in the air", 230),
(9, 30, "You know they are a liar", 190)

私が期待する結果は次のとおりです。

id | authorId | answer                                             | votes
 6 |       32 | I'm your pole and all you're wearing is your shoes | 540
 3 |       31 | Everything's gonna be allright                     | 350
 9 |       30 | You know they are a liar                           | 190

基本的に、著者ごとに最良の回答を選択し、最良の回答が得られた投票数で結果を並べ替える必要があります。同じ著者による 2 つの回答が同じ投票数になる場合があります。次に、最初に投稿されたもの (低い ID) のみを選択する必要があります (回答 #3 と #4 で示されているように)。同じ著者による 2 つの異なる回答が結果に表示されることはありません。各著者は 1 回のみ当選します。

私は検索して検索し、再試行しましたが、現時点ではかなり洗脳されていると感じています..これは単一のSQLクエリでは実行できない可能性があります。その場合は、アプリケーションが PHP で作成されていることに注意してください。すべての答えを取得しORDER BY votes desc, id ascて結果を反復処理し、すべてのauthorIds を覚えて、authorId既に見た . ...あまりにも多くの行を削除する場合など、オフセットを使用してクエリを再度実行する必要がある可能性があります..しかし、最終的には、単一クエリのソリューションが過度に複雑であるか、まったくない場合に最適なソリューションになる可能性があります...

何か案は?:o)

4

4 に答える 4

5
SELECT id, authorId, answer, votes
FROM (  SELECT id, authorId, answer, votes
        FROM answers
        ORDER BY votes DESC) AS h
GROUP BY authorId

GROUP BYこのちょっとした巧妙なトリックは、各ケースの最初の行を取得することに基づいて構築されています。通常、これはデフォルトですORDER BY id ASCが、このサブクエリを介して、それぞれの最初の行でauthorId最も高いvotes.

注: Iin Elder が述べたように、このソリューションはONLY_FULL_GROUP_BYアクティブでは機能せず、MySQL でのみ機能します。このソリューションは、この動作を確認するドキュメントがないため、ある程度サポートされていません。それは私にとってはうまく機能しますが、常にうまく機能しています。

この方法は、最新のMySQL on sqlfiddle で引き続き機能します。

于 2012-09-10T21:30:19.397 に答える
3

副選択を使用できます。

select min(a1.id), a1.authorid, a2.mxvotes
from answers a1
inner join
(
  select authorid, max(votes) mxvotes
  from answers
  group by authorid
) a2
  on a1.authorid = a2.authorid
  and a1.votes = a2.mxvotes
group by a1.authorid, a2.mxvotes
order by mxvotes desc

SQL FiddlewithDemoを参照してください

于 2012-09-10T20:28:14.840 に答える
1

素晴らしい質問です、ダン。

MySQL には、これを簡単に解決するための分析機能がありません。同様の質問が Oracle に寄せられており、MAX 関数で OVER 句を使用して解決されました。これは SQL Server でも機能します。

MySQL でそれを行うには、サブクエリを使用する必要があります。これは私のために働く:

SELECT
  id,
  authorId,
  answer,
  votes
FROM answers AS firsts
WHERE id = (
  SELECT
    MIN(id)
  FROM answers AS favorites
  WHERE
    votes = (
      SELECT MAX(votes)
      FROM answers AS author_max
      WHERE author_max.authorId = favorites.authorID
    ) AND
    favorites.authorId = firsts.authorId 
)
ORDER BY votes DESC;

実行可能な例については、私のsqlfiddleを参照してください。

于 2012-09-10T20:52:31.657 に答える
0
select * from (select * from answers order by votes desc) as temp group by authorId
于 2012-09-11T15:31:38.143 に答える