2017-01-04 8 views
1

ユーザーから再生された上位3曲をクエリするにはどうすればよいですか?ユーザーIDとSONG_NAMEここCHAR(255)ユーザーが再生する上位3曲をクエリするにはどうすればよいですか?

あるテーブルの説明である:私はsong_namesを変更

+--------+-----------+---------------------+ 
    | userid | song_name | timestamp   | 
    +--------+-----------+---------------------+ 
    | 123 | A   | 2017-01-04 01:35:41 | 
    | 123 | B   | 2017-01-04 01:37:57 | 
    | 123 | B   | 2017-01-04 01:38:32 | 
    | 123 | B   | 2017-01-04 01:38:42 | 
    | 123 | C   | 2017-01-04 01:38:46 | 
    | 123 | D   | 2017-01-04 01:38:50 | 
    | 123 | E   | 2017-01-04 01:38:54 | 
    | 123 | E   | 2017-01-04 01:38:59 | 
    | 123 | A   | 2017-01-04 01:39:03 | 
    | 123 | E   | 2017-01-04 01:39:20 | 

:ここ

+-----------+-----------+------+-----+-------------------+-------+ 
| Field  | Type  | Null | Key | Default   | Extra | 
+-----------+-----------+------+-----+-------------------+-------+ 
| userid | char(255) | YES |  | NULL    |  | 
| song_name | char(255) | YES |  | NULL    |  | 
| timestamp | timestamp | NO |  | CURRENT_TIMESTAMP |  | 
+-----------+-----------+------+-----+-------------------+-------+ 

は、テーブルがどのように見えるかのサンプルですあなたが理解しやすいように手紙を書いてください。 トップソングは実際には、song_nameがユーザーIDに対応する時間数になります。

現在のコード:

SELECT userid, GROUP_CONCAT(DISTINCT song_name 
ORDER BY song_name) 
top_songs 
FROM sampleTable3 
GROUP BY userid; 

どのように私はそれがほとんどの演奏によって上位3曲順をプリントアウトだろうと、それを変えるのでしょうか?

私の質問は、特定の値がuseridに対応する回数を聞いています。

+0

を "トップ3" の基準は何か? –

+0

を参照してください。 @ AndriyIvaneyko。 –

+0

グループごとのトップ質問である場合は、それもSOに関する回答があります:http://stackoverflow.com/questions/12113699/get-top-n-records-for-each-group-of-grouped -results – Shadow

答えて

0

を試してみてください。 (申し訳ありませんゴードン)

SELECT userid, GROUP_CONCAT(song_name ORDER BY cnt DESC SEPARATOR '|') 
FROM (SELECT us.*, 
      (@rn := if(@u = userid, @rn + 1, 
         if(@u := userid, 1, 1) 
         ) 
      ) as rn 
     FROM (SELECT userid, song_name, COUNT(*) as cnt 
      FROM sampleTable3 
      GROUP BY userid, song_name 
      ORDER BY userid, COUNT(*) DESC 
      ) us CROSS JOIN 
      (SELECT @u := -1, @rn := 0) t1 
    ) u 
WHERE rn <= 3 
GROUP BY userid; 

一つだけ与えられたユーザのためにトップ3の曲を検索したい場合は、使用します。

select userid, songname 
from songs 
where userid = 123 
group by userid, songname 
order by count(*) desc 
limit 3; 

SQLFiddle

0

実は、あなたがこの方法を追求することができますが、最初に集約し、group_concat()ロジックを調整する必要があります。

を中間結果が限られているので、しかし、あなたは、文字列のオーバーフローエラーを取得する可能性があります。システムパラメータである制限を変更することができます。

別の方法は、変数を使用しています。

SELECT userid, GROUP_CONCAT(song_name ORDER BY cnt DESC SEPARATOR '|') 
FROM (SELECT us.*, 
      (@rn := if(@u = userid, @rn + 1, 
         if(@u := userid, 1, 1) 
         ) 
      ) as rn 
     FROM (SELECT userid, song_name, COUNT(*) as cnt 
      FROM sampleTable3 
      GROUP BY userid, song_name 
      ORDER BY userid, COUNT(*) DESC 
      ) us CROSS JOIN 
      (SELECT @u := -1, @rn := 0) 
     GROUP BY userid 
    ) u 
WHERE rn <= 3; 
+1

@HuyVo。 。 。この特定の質問は、MySQLがデータ解析のためにデータを格納するのに使用されるべきではない理由の一つです。これは、ANSI準拠のウィンドウ関数をサポートするデータベースでははるかに簡単です。 –

1

はゴードンの答えからコピーされ、固定この

select count(*) as cnt,song_name,userid from songs group by song_name order by cnt DESC limit 3; 

demo on sqlfiddle

+0

は機能しません。また、テーブル名はsampletable3です –

+0

@Huyなぜうまくいかないのですか? – denny

+0

は問題ではありません。作業スタッドを維持してください。 –

関連する問題