首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL GROUP BY rand()?

MySQL GROUP BY rand()?
EN

Stack Overflow用户
提问于 2012-05-19 13:41:35
回答 4查看 2.1K关注 0票数 2

所以,我遇到了一个有趣的问题。我相信有一个简单的解决方案,但我不确定它是什么。:)

基本上,想象一个非常简单的数据库,如下所示:

代码语言:javascript
复制
----------------
T1
----------------
  r  |  nID
---------------
  1  |   A
  2  |   B
----------------




----------------
T2
----------------
 nID |  val
---------------
  A  |   XXX
  B  |   L
  B  |   M
  B  |   N
  B  |   P
----------------

基本上,表2引用了表1。现在,我想从A或B中随机选择一行。但是,我想首先将A和B随机化,然后选择一个相关的值。

换句话说,抛硬币:正面,XXX。Tails、L, M, N,P

我当前的查询连接两个表,orders by RAND(),然后是LIMIT 1。然而,这使得选择B值的几率比选择A值的可能性大得多。我使用PHP,所以我可以很容易地运行两个查询,但是运行一个查询会更整洁,所以我想看看你们推荐的是什么。

有什么解决方案吗?=)

编辑:

以下是我当前的查询,但它不起作用。不知道为什么!

代码语言:javascript
复制
SELECT *
FROM t2
WHERE
    nID =
    (
        SELECT nID
        FROM t1
        ORDER BY RAND()
        LIMIT 1
    )
ORDER BY RAND()
LIMIT 1

编辑2:

为了演示我遇到的问题,我创建了一个测试用例。首先,我创建了以下表:

我希望选择XXX的几率与选择LMNP的几率相同。我的查询应该可以做到这一点,对吧?所以我测试了一下。以下脚本运行该查询5000次,并对结果进行计数。它们应该是50-50,其中XXX大约出现2500次,其他所有内容也出现大约2500次。

代码语言:javascript
复制
$a = 0;
$b = 0;
$i = 0;
while ($i < 5000)
{
    $query = mysql_query("
        SELECT *
        FROM t2
        WHERE
            nID =
            (
                SELECT nID
                FROM t1
                ORDER BY RAND()
                LIMIT 1
            )
        ORDER BY RAND()
        LIMIT 1
        ") or die(mysql_error());

    $result = mysql_fetch_array($query);
    if ($result['val'] == 'XXX')
    {
        $a++;
    }
    else
    {
        $b++;
    }

    $i++;
}

echo "XXX - $a<br />";
echo "Other - $b<br />";

结果如下:

代码语言:javascript
复制
XXX - 937
Other - 4063

让我们再运行一次。

代码语言:javascript
复制
XXX - 968
Other - 4032

让我们再运行一次。

代码语言:javascript
复制
XXX - 932
Other - 4068

根据我的疑问,这几乎不是我们期望看到的50-50的比例。到底是怎么回事?谢谢你们的帮助,伙计们!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-05-21 01:32:04

您可能希望问题中的子查询在每个外部查询中运行一次,但看起来情况并非如此。我认为下面可能会给你你想要的东西:

代码语言:javascript
复制
SET @randID = (SELECT nID
FROM T1
ORDER BY RAND()
LIMIT 1);

SELECT VAL
FROM T2
WHERE nID = @randID
ORDER BY RAND()
LIMIT 1;

(SQL Fiddle)

票数 2
EN

Stack Overflow用户

发布于 2012-05-21 02:17:38

你的示例内部查询被多次求值,如果你想让它选择A或B一次,你需要重写它,例如作为一个JOIN

代码语言:javascript
复制
SELECT q2.nID, q2.val
FROM ( SELECT nID FROM T1 ORDER BY RAND() LIMIT 1 ) q1
JOIN T2 q2 ON q1.nID = q2.nID
ORDER BY RAND()
LIMIT 1

如果您使用的是小表,那么这个查询应该没问题,但是请阅读here for example,了解为什么不应该对大表使用ORDER BY RAND()

演示here

票数 2
EN

Stack Overflow用户

发布于 2012-05-19 13:52:11

请尝试下面给出的查询

代码语言:javascript
复制
SELECT `table2`.*  FROM `table2` WHERE table2.field1 = (Select table1.field2 from table1 order by RAND() limit 0,1) LIMIT 0,1

在这里,我假设两个表的列名分别为field1和field2,因此请根据您的表结构使用字段名。

谢谢

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10662647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档