Mysql 我如何查询用户播放的前三首歌曲?

Mysql 我如何查询用户播放的前三首歌曲?,mysql,Mysql,如何查询用户播放的前3首歌曲?用户ID和歌曲名称为char255 以下是表格的说明: +-----------+-----------+------+-----+-------------------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+-----------+------+-----+-------------------+-------+ |

如何查询用户播放的前3首歌曲?用户ID和歌曲名称为char255

以下是表格的说明:

 +-----------+-----------+------+-----+-------------------+-------+
 | Field     | Type      | Null | Key | Default           | Extra |
 +-----------+-----------+------+-----+-------------------+-------+
 | userid    | char(255) | YES  |     | NULL              |       |
 | song_name | char(255) | YES  |     | NULL              |       |
 | timestamp | timestamp | NO   |     | CURRENT_TIMESTAMP |       |
 +-----------+-----------+------+-----+-------------------+-------+
下面是表格的示例:

    +--------+-----------+---------------------+
    | 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 |
为了让你更好地理解,我把歌曲的名字改成了字母。 一首顶级歌曲实际上是一首歌的名字与用户ID对应的次数

当前代码:

 SELECT userid, GROUP_CONCAT(DISTINCT song_name 
 ORDER BY song_name) 
 top_songs
 FROM sampleTable3
 GROUP BY userid; 
我该如何修改它以打印出播放次数最多的前3首歌曲


我的问题是询问一个特定值与userid对应多少次

实际上,您可以采用这种方法,但您需要先进行聚合并调整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;
试试这个

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

从戈登的答案中复制并修正。对不起,戈登

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;

前三名的标准是什么?请参见编辑@AndriyIvaneyko。如果这是一个每组n首的问题,那么它也有一个答案:@Shadow,代码计算有多少个值对应于列。在我的例子中,它会计算有多少首歌曲对应于userid。不起作用。此外,表名为sampletable3@Huy为什么不工作?没关系,你明白你的意思了。继续努力。@HuyVo。这个特殊的问题是为什么不应该使用MySQL存储数据进行数据分析的一个很好的原因。在支持符合ANSI标准的窗口函数的数据库中,这将容易得多。
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;
select userid, songname
from songs
where userid = 123
group by userid, songname
order by count(*) desc
limit 3;