MySQL: применение случайной сортировки по нескольким столбцам - PullRequest
1 голос
/ 22 июня 2010

Чтобы иметь хорошо скремблированную таблицу (для психологического эксперимента), я бы хотел отсортировать каждый столбец моего массива по RAND ().Во всем этом коде работает:

SELECT Sort.Variable1, Sort.Variable2 FROM Sort ORDER BY Variable1, Variable2 ASC LIMIT 0 , 30

замена «ASC» на «RAND ()» делает запрос неудачным.Может кто-нибудь дать мне совет (даже решение с помощью PHP)?

Спасибо

Редактировать:

Благодаря всем вашим ответам, я наконец сделал это.Вот мой PHP-код для этого (и извините за старомодные-не-совершенно-новые-PDO-запросы).Даже если это может быть бесполезно, я отправляю это:

           $i=0;
        //Describe to retrieve variables' names
        $sqlCol= 'DESCRIBE Sort';
        $sqlCol= mysql_query($sqlCol);
        while ($res=mysql_fetch_array($sqlCol)) {
            $var[$i]=$res['Field'];
            $i++;
        }
        $NbCol=mysql_num_rows($sqlCol); //Number of column to shuffle


        // Number of items for each column 
        $sqlCount= 'SELECT COUNT(*) FROM Sort';
        $req2= mysql_query($sqlCount) or die ('Err');
        $NbLignes=  mysql_result($req2,0,0) or die ();//Number of rows


        //Data array
        $sql= "SELECT * FROM Sort";
        $req= mysql_query($sql) or die ('Err');
        $sort=mysql_fetch_array($req);
        for($i=0;$i<$NbCol;$i++) {
            ${'sql'.$i}='SELECT * FROM Sort ORDER BY RAND()';
            ${'input'.$i} = mysql_query(${'sql'.$i});
            while(${'array'.$i}=mysql_fetch_array(${'input'.$i})) {
                $bigArray[$i][]=${'array'.$i}[$i];
            }
        }

            for($i=0;$i<$NbLignes;$i++) {
                echo '<div id="q'.$i.'"style="margin-bottom: 50px; float:left">Question '.($i+1);
                echo '<ul id="sortable'.$i.'" class="sortable">';
                for($j=0;$j<$NbCol;$j++) {
                    echo '<li class="ui-state-default" id="'.$var[$j].$i.'" name="'.$var[$j].$i.'">'. $bigArray[$j][$i].'</li>';

                }
                echo '</ul></div>';
            }

Ответы [ 3 ]

2 голосов
/ 22 июня 2010

Использование ORDER BY RAND() не рандомизирует столбцы - оно рандомизирует строки.

Чтобы рандомизировать каждый столбец отдельно в SQL, вы можете:

  • создать набор результатов для каждого столбца отдельно
  • рандомизируйте порядок каждого из них
  • объединить столбцы по номеру строки

К сожалению, команда разработчиков MySQL еще не реализовала ROW_NUMBER, что облегчило бы эту задачу, но вы можете обойти ее, смоделировав ROW_NUMBER с помощью переменных:

SELECT
    Column1,
    Column2
FROM
(
    SELECT Column1, @rn1 := @rn1 + 1 AS rank
    FROM Table1, (SELECT @rn1 := 0) vars
) T1
JOIN
(
    SELECT Column2, @rn2 := @rn2 + 1 AS rank
    FROM Table1, (SELECT @rn2 := 0) vars
    ORDER BY RAND()
) T2
ON T1.rank = T2.rank
0 голосов
/ 22 июня 2010

Вот один из возможных способов сделать то, что вы хотите, используя PHP. В примере кода я генерирую список чисел и помещаю их в массив. Вам нужно будет взять список из вашей базы данных.

<?php

// Create 20 rows.
$rows = 20;

// Create an empty array to hold sorted values.
$sort = array();

// Fill the array with ascending/descending numbers.
for ($i = 0; $i < $rows; $i++) {
    $sort[$i]['var1'] = $i + 1;
    $sort[$i]['var2'] = $rows - $i; 
}

// Display the sorted array.
print "Sorted:\n";
print_rows($sort);

// Here's where the important bit happens:

// Create two arrays, each containing a list of the
// array keys from the sorted array (one for each column).
$var1 = array_keys($sort);
$var2 = array_keys($sort);

// Shuffle each list or array keys (one for each column).
shuffle($var1);
shuffle($var2);

// Create an empty array to hold shuffled values.
$shuffle = array();

// For every row in the list of shuffled keys, get
// the matching value from the sorted array, and
// place it in the shuffled array.
for ($i = 0; $i < $rows; $i++) {
    $shuffle[$i]['var1'] = $sort[$var1[$i]]['var1'];
    $shuffle[$i]['var2'] = $sort[$var2[$i]]['var2'];
}

// Display the shuffled array.
print "\nShuffled:\n";
print_rows($shuffle);


function print_rows($array) {
    print "Row | Var 1 | Var2\n";
    print "------------------\n";

    foreach ($array as $key=>$row) {
        printf("%3d | %5d | %4d\n", $key, $row['var1'], $row['var2']);
    }
}

?>

Вот вывод:

Sorted:
Row | Var 1 | Var2
------------------
  0 |     1 |   20
  1 |     2 |   19
  2 |     3 |   18
  3 |     4 |   17
  4 |     5 |   16
  5 |     6 |   15
  6 |     7 |   14
  7 |     8 |   13
  8 |     9 |   12
  9 |    10 |   11
 10 |    11 |   10
 11 |    12 |    9
 12 |    13 |    8
 13 |    14 |    7
 14 |    15 |    6
 15 |    16 |    5
 16 |    17 |    4
 17 |    18 |    3
 18 |    19 |    2
 19 |    20 |    1

Shuffled:
Row | Var 1 | Var2
------------------
  0 |     8 |    2
  1 |    19 |   12
  2 |    14 |    5
  3 |    16 |   17
  4 |     2 |    8
  5 |    11 |    4
  6 |     7 |   11
  7 |     9 |   10
  8 |    12 |    1
  9 |     5 |    9
 10 |    13 |   20
 11 |    10 |    6
 12 |    17 |   19
 13 |    18 |   18
 14 |     4 |   14
 15 |    20 |    7
 16 |     3 |   16
 17 |    15 |   15
 18 |     6 |    3
 19 |     1 |   13

Код немного груб и готов. Я уверен, что есть несколько способов улучшить это. Например, вы можете изменить его, чтобы он мог обрабатывать переменное количество столбцов. Однако основная идея есть.

Edit:

Вот приведенная в порядок версия кода, которая будет обрабатывать переменное число столбцов:

// Here's where the important bit happens:

// Create an empty array to hold shuffled values.
$shuffle = array();

// Get the name of each column (key) in the array.
foreach (array_keys($sort[0]) as $col) {
    // Create an array of keys containing a list of the
    // array keys from the sorted array.
    $keys = array_keys($sort);

    // Shuffle each list or array keys.
    shuffle($keys);

    // For every row in the list of shuffled keys, get
    // the matching value from the sorted array, and
    // place it in the shuffled array.
    for ($i = 0; $i < $rows; $i++) {
        $shuffle[$i][$col] = $sort[$keys[$i]][$col];
    }
}

// Display the shuffled array.
print "\nShuffled:\n";
print_rows($shuffle);
0 голосов
/ 22 июня 2010

Вы можете сделать 2 SQL-утверждения:

 SELECT Sort.Variable1 FROM Sort ORDER BY RAND(), Variable1 LIMIT 0 , 30
 SELECT Sort.Variable2 FROM Sort ORDER BY RAND(), Variable2 LIMIT 0 , 30

если вам нужно случайное использование PHP в массиве:

<?php
// load all table values in array i just set them
$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank"); 
$rand_keys = array_rand($input, 2);
echo $input[$rand_keys[0]] . "\n";
echo $input[$rand_keys[1]] . "\n";
?>
...