2010-06-22 2 views
1

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

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

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

Благодаря

Edit:

Благодаря все ваши ответы, я, наконец, сделал это. Вот мой PHP-код для этого (и извините за старые-не-brand-new-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>'; 
      } 
+0

Можете ли вы объяснить, почему 'ORDER BY RAND()' не будет делать? –

+0

Вы уже не задавали этот вопрос в немного другом обличье? Http: // StackOverflow.com/questions/3075115/mysql-php-order-each-column-of-a-array-randomly – Mike

+0

Я не буду отрицать, что вы прав; Я пробовал все возможное, чтобы сделать это с помощью PHP (while, for, shuffle() ...) с двух дней, и я просмотрел все сообщения по этому вопросу, но не могу найти подходящий способ заставить его работать , Мне жаль, что опубликуйте это снова в другой оболочке, но эта проблема действительно сводит меня с ума, и я смотрю на все возможные способы преодоления этой проблемы. – Coronier

ответ

0

Вот один из возможных методов делайте то, что хотите, используя 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

Это то, что я искал. Я не могу поблагодарить вас достаточно, теперь я могу продолжать кодирование без головной боли. Спасибо за ваше полное и терпеливое объяснение. – Coronier

2

Использование 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

Прошу прощения, но если я знаю, как присоединиться к таблицам, у меня нет идей, как объединить эти результаты вместе. Не могли бы вы дать мне руку на это, пожалуйста? – Coronier

+0

Это приведет к тому, что данные будут полностью упорядочены, и только строки с дубликатами в Variable1 и Variable2 будут рандомизированы между собой. Кажется, это не то, что ищет OP ... –

+0

@Joseph Mastey: Первый бит просто объяснял синтаксическую ошибку - теперь я удалил эту часть, чтобы избежать путаницы. Вы видели второе предложение, которое я сделал в своем ответе? Я теперь обновил свой ответ, чтобы опубликовать фактический SQL, чтобы вы могли попробовать запустить его для себя и сообщить мне, если вы считаете, что он все еще не работает. –

0

Вы можете сделать 2 statments 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: [array_rand] [1]

<?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"; 
?> 
Смежные вопросы