我需要根据他们的类型生成歌曲列表。列表中返回的每种类型的数量取决于用户如何加权。
所以他们可能会设置......
Rock - 5 out of 10
Pop - 2 out of 10
Dance - 1 out of 10
Folk - 10 out of 10
数据库表中的每个曲目都有一个genre_id
:
Rock = 1
Pop = 2
Dance = 3
Folk = 4
他们还可以选择要返回的曲目数量,因此可能是10,20 ...最多100。
我有2张桌子
TRACKS
id (INT)
track_name (VARCHAR)
genre_id (INT)
GENRES
id (INT)
name (VARCHAR)
我正在使用MySQL和PHP来实现这一目标,任何帮助都会很棒
答案 0 :(得分:1)
这很有效。但是,在某些情况下,歌曲总数会出现舍入误差(从不超过1);
/*
* It's more likely to fill the first two arrays from a query, but for
* the example I defined them like
* genreId => value
*/
$genres = array(
1 => 'rock',
2 => 'pop',
3 => 'dance',
4 => 'folk',
27 => 'classical'
);
$pointsPerGenre = array(
1 => 5, //rock, 5 out of 10
2 => 2, //pop, 2 out of 10
3 => 1, //etc...
4 => 10,
27 => 7
);
$totalPoints = array_sum($pointsPerGenre);
$numberOfSongs = 20;
$songsPerPoint = $numberOfSongs / $totalPoints;
$songsPerGenre = array();
foreach(array_keys($genres) as $genreId)
{
$songsPerGenre[$genreId] = round($pointsPerGenre[$genreId] * $songsPerPoint);
}
$queryParts = array();
foreach($songsPerGenre as $genreId => $numberOfSongsPerGenre)
{
$queryParts[] = "(SELECT * FROM TRACKS WHERE genre_id = $genreId ORDER BY RAND() LIMIT $numberOfSongsPerGenre)";
}
$query = implode("\nUNION\n", $queryParts);
这将输出以下查询(在这里您可以看到舍入错误,在这种情况下用户会收到一首奖励歌曲):
(SELECT * FROM TRACKS WHERE genre_id = 1 ORDER BY RAND() LIMIT 4)
UNION
(SELECT * FROM TRACKS WHERE genre_id = 2 ORDER BY RAND() LIMIT 2)
UNION
(SELECT * FROM TRACKS WHERE genre_id = 3 ORDER BY RAND() LIMIT 1)
UNION
(SELECT * FROM TRACKS WHERE genre_id = 4 ORDER BY RAND() LIMIT 8)
UNION
(SELECT * FROM TRACKS WHERE genre_id = 27 ORDER BY RAND() LIMIT 6)