0

我需要根据它们的流派生成歌曲列表。列表中返回每种类型的多少取决于用户对它们的加权方式。

所以他们可能会设置...

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 来完成这个,任何帮助都会很棒

4

1 回答 1

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)
于 2012-10-18T14:16:27.877 回答