MySQL результат с множественным вхождением элемента в зависимости от важности - PullRequest
1 голос
/ 05 сентября 2011

Может кто-нибудь сказать мне, возможно ли получить список записей MySQL в зависимости от важности каждой строки.Допустим, у меня есть 4 записи в таблице (идентификатор, имя, важность).0 = наибольшая важность.

id | file      | importance
---|-----------|-----------
1  | movie.mp4 | 0
2  | image.jpg | 1
3  | movie1.mp4| 2
4  | movie2.mp4| 2

хотите создать массив из 20 записей, которые заполняются результатом из 4 элементов (пример 5 * movie.mp4, 3 * image.jpg, 2 * ..., 2 * ...), но хитрость в том, что элементы должны быть расположены в массиве случайным образом, а не друг за другом.

$file[] = movie.mp4;
$file[] = movie2.mp4;
$file[] = image.jpg;
$file[] = movie.mp4;
$file[] = image.jpg;
$file[] = movie1.mp4;
$file[] = movie.mp4;
$file[] = image.jpg;
$file[] = movie.mp4;
$file[] = movie1.mp4;
$file[] = movie.mp4;
$file[] = movie2.jpg;

Надеюсь, вы поняли, или же, пожалуйста, спросите:)

Ответы [ 2 ]

1 голос
/ 05 сентября 2011
SELECT draw_bucket.file
FROM (
    SELECT row,
    FLOOR( RAND() * ( SELECT SUM( POW( 2, 2 - importance ) ) FROM files ) ) AS rnd
    FROM ( 
       (SELECT 1 AS row) UNION (SELECT 2) UNION (SELECT 3) UNION (SELECT 4) UNION
       (SELECT 5) UNION (SELECT 6) UNION (SELECT 7) UNION (SELECT 8) UNION
       (SELECT 9) UNION (SELECT 10) UNION (SELECT 11) UNION (SELECT 12) UNION
       (SELECT 13) UNION (SELECT 14) UNION (SELECT 15) UNION (SELECT 16) UNION
       (SELECT 17) UNION (SELECT 18) UNION (SELECT 19) UNION (SELECT 20)
    ) AS row_nums
) AS rows
INNER JOIN (
    SELECT @row := @row + 1 AS row, file
    FROM ( 
       (SELECT 1 AS cnt) UNION (SELECT 2) UNION (SELECT 3) UNION (SELECT 4)
    ) AS cnt
    INNER JOIN files
    ON( cnt.cnt <= POW( 2, 2 - files.importance ) )
    INNER JOIN ( SELECT @row := -1 ) AS INIT
) AS draw_bucket
ON( rows.rnd = draw_bucket.row )

число (SELECT 1), (SELECT 2), ... в подзапросе row_nums должно равняться числу записей, которое вы хотите, а в подзапросе cnt должно равняться 2 ^ минимальный приоритет.

Вы можете упростить это, выполнив большинствоработы в PHP (например).Выполните SELECT * и заполните массив следующим образом:

$items = array(
    array( 'file' => 'movie.mp4', 'importance' => 0 ),
    array( 'file' => 'image.jpg', 'importance' => 1 ),
    array( 'file' => 'movie1.mp4', 'importance' => 2 ),
    array( 'file' => 'movie2.mp4', 'importance' => 2 )
);

Затем выполните рисование в PHP:

$minImportance = 2;

$drawBucket = array();
foreach( $items as $index => $item ) {
    for( $i = 0; $i < pow( 2, $minImportance - $item['importance'] ); ++$i ) {
        $drawBucket[] = $index;
    }
}

$output = array();
for( $i = 0; $i < 20; ++$i ) {
    $randomIndex = mt_rand( 0, count($drawBucket) - 1 );
    $output[] = $items[ $drawBucket[$randomIndex] ][ 'file' ];
}

var_dump( $output );
0 голосов
/ 05 сентября 2011

Мы можем сделать это просто с php:

<?php
function cmpf(a,b)
{
    return a['importance'] - b['importance'];
}
$arr = array();
$res = mysql_query("SELECT * from tbname ORDER BY importance;");
$k = 0;
while ($row = mysql_fetch_assoc($res))
{
  $arr[$k] = $row;
  $k++
}
shuffle($arr);
usort($arr, "cmpf");
?>
...