# 随机选择记录

在本教程中，您将学习从MySQL中的数据库表中查询选择随机记录的各种技术。

有时，必须从表中选择随机记录，例如：

* 在博客中选择一些随机的帖子，并在侧边栏中显示。
* 选择一个随机报价来显示“当天的报价”小部件。
* 在画廊中选择随机图片，并将其用作精选照片。

## MySQL使用ORDER BY RAND()选择随机记录

MySQL没有任何内置语句从数据库表中选择随机记录。为了实现这一点，您可以使用`RAND`函数。以下查询从数据库表中选择一个随机记录：

```sql
SELECT 
    *
FROM
    tbl
ORDER BY RAND()
LIMIT 1;
```

让我们更详细地查看上面的查询语句 -

* `RAND()`函数为表中的每一行生成一个随机值。
* [ORDER BY](http://www.yiibai.com/mysql/order-by.html)子句通过`RAND()`函数生成的随机数对表中的所有行进行排序。
* [LIMIT](http://www.yiibai.com/mysql/limit.html)子句选择随机排序的结果集中的第一行。

如果要从数据库表中选择`N`个随机记录，则需要如下更改`LIMIT`子句：

```sql
SELECT 
    *
FROM
    table
ORDER BY RAND()
LIMIT N;
```

例如，要在`customers`表中查询选择`5`个随机客户，请使用以下查询：

```sql
SELECT 
    t.customerNumber, t.customerName
FROM
    customers AS t
ORDER BY RAND()
LIMIT 5;
```

因为是随机，您可能会得到一个不同的结果集。

这种技术与一个小表上非常好。但是对于大表将是非常缓慢的，因为MySQL必须对整个表进行排序以选择随机数。查询的速度也取决于表中的行数。 表的行数越多，生成的随机数所花的时间就越多。

## MySQL使用INNER JOIN子句选择随机记录

该技术要求您要选择随机记录的表具有[自动增量](http://www.yiibai.com/mysql/sequence.html)[主键](http://www.yiibai.com/mysql/primary-key.html)字段，并且序列中没有间隙。

以下查询根据主键列生成随机数：

```sql
SELECT 
        ROUND(RAND() * ( SELECT 
                    MAX(id)
                FROM
                    table)) as id;
```

我们可以通过上述查询返回的结果集[连接](http://www.yiibai.com/mysql/inner-join.html)表，如下所示：

```sql
SELECT 
    t.*
FROM
    table AS t
        JOIN
    (SELECT 
        ROUND(RAND() * (SELECT 
                    MAX(id)
                FROM
                    table )) AS id
    ) AS x
WHERE
    t.id >= x.id
LIMIT 1;
```

使用这种技术，您可多次执行查询以获取多个随机行，因为如果增加限制，则查询将仅给出从随机选择的行开始的顺序行。

以下查询从`customers`表返回一个随机客户。

```sql
SELECT 
    t.customerNumber, t.customerName
FROM
    customers AS t
        JOIN
    (SELECT 
        ROUND(RAND() * (SELECT 
                    MAX(customerNumber)
                FROM
                    customers)) AS customerNumber
    ) AS x
WHERE
    t.customerNumber >= x.customerNumber
LIMIT 1;
```

## MySQL使用变量选择随机记录

如果表的`id`列的值范围为`1 .. N`，并且范围内没有间隙，则可以使用以下技术：

* **首先**，选择`1..N`范围内的随机数字。
* **第二步**，根据随机数选择记录。

以下语句可以完成此操作：

```sql
SELECT 
    table. *
FROM
    (SELECT 
        ROUND(RAND() * (SELECT 
                    MAX(id)
                FROM
                    table)) random_num,
            @num:=@num + 1
    FROM
        (SELECT @num:=0) AS a, table
    LIMIT N) AS b,
    table AS t
WHERE
    b.random_num = t.id;
```

请注意，用户定义的变量是连接特定的。这意味着这种技术不能与连接池一起使用。此外，主键必须是整数类型，其值必须在没有间隙的序列中。

在本教程中，我们向您展示了从表中选择随机记录的几种技术。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hezhiqiang-book.gitbook.io/mysql/di-er-zhang/sui-ji-xuan-ze-ji-lu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
