MySQL:对多列应用随机排序

时间:2010-06-22 08:33:53

标签: php mysql sorting random

为了有一个很好的扰乱表(用于心理学实验),我想用RAND()对我的数组的每一列进行排序。 通过此代码工作:

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

用“RAND()”替换“ASC”会使查询失败。有人可以给我一个建议(甚至是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 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

您可以使用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数组:[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";
?>

答案 2 :(得分: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

代码有点粗糙,准备好了。我确信有很多方法可以改进它。例如,您可以更改它,以便它能够处理可变数量的列。但是,基本的想法就在那里。

修改

这是一个整理的代码版本,它将处理可变数量的列:

// 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);