【问题标题】:MySQL: applying a random sort on multiple columnsMySQL:对多列应用随机排序
【发布时间】:2011-03-06 17:03:12
【问题描述】:

为了有一个很好的打乱表(用于心理实验),我想按 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>';
            }

【问题讨论】:

  • 你能解释一下为什么ORDER BY RAND() 不行吗?
  • 您还没有以稍微不同的方式问过这个问题吗? stackoverflow.com/questions/3075115/…
  • 我不会否认你是真的;自 2 天以来,我已经尽一切可能用 PHP 来做到这一点(虽然,对于,shuffle()...),我已经查看了关于这个主题的每一篇文章,但我找不到令人满意的方法来让它工作.我很抱歉在另一个 shell 中再次发布这个问题,但这个问题真的让我发疯了,我想尽办法克服这个问题。

标签: php mysql sorting random


【解决方案1】:

使用 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 和变量 2 中具有重复的行会在彼此之间随机化。似乎不是 OP 正在寻找的东西......
  • @Joseph Mastey:第一部分只是解释语法错误——我现在删除了那部分以避免混淆。您看到我在回答中提出的第二个建议了吗?我现在更新了我的答案以发布所需的实际 SQL,因此您可以尝试自己运行它,如果您认为它仍然不起作用,请告诉我。
【解决方案2】:

这是使用 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);

【讨论】:

  • 这完全是我想要的。我非常感谢你,我现在可以继续编码而不会头痛。感谢您完整而耐心的解释。
【解决方案3】:

您可以通过 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";
?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-08
    • 2013-06-12
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2011-05-21
    • 2012-07-26
    • 2012-08-04
    相关资源
    最近更新 更多