2012-10-18 3 views
0

장르에 따라 노래 목록을 생성해야합니다. 목록에서 반환되는 각 장르의 양은 사용자가 가중치를 부여하는 방법에 따라 다릅니다.x 가중치 수를 기준으로 임의의 행 선택

그래서 그들은 설정할 수 있습니다 ...

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) 
+0

도움 주셔서 감사합니다! 지금 나에게 의미가있다. 나는 PHP RAND/limit를 사용하여 ORDER BY RAND()를 대체 할 것이라고 생각한다. – Mark

관련 문제