Skip to content

MySQL 限制查询结果

PHP:从 MySQL/MariaDB 限制数据选取

Section titled “PHP:从 MySQL/MariaDB 限制数据选取”

在使用 MySQL 或 MariaDB 等数据库处理大型数据集时,一次检索所有记录可能会效率低下并减慢应用程序速度。SQL LIMIT 子句对于实现分页至关重要,它允许您以更小、更易于管理的块(页面)获取数据。

LIMIT 子句指定返回的最大行数。

要从名为 Orders 的表中只选取前 30 条记录,SQL 查询将是:

SELECT * FROM Orders LIMIT 30;

此查询根据表的默认顺序(或指定的 ORDER BY 子句)返回找到的前 30 行。

要实现分页,通常需要跳过一定数量的记录。例如,要显示第 16 条到第 25 条记录(总共 10 条记录,从前 15 条之后开始),您可以使用 OFFSET 关键字:

SELECT * FROM Orders ORDER BY order_date DESC LIMIT 10 OFFSET 15;

此查询表示:“跳过前 15 条记录(OFFSET 15),然后返回接下来的 10 条记录(LIMIT 10)。”请注意添加了 ORDER BY,这对于一致的分页结果至关重要。

MySQL/MariaDB 也支持 LIMIT offset, row_count 的简写逗号语法:

SELECT * FROM Orders ORDER BY order_date DESC LIMIT 15, 10;

请注意:在逗号语法中,第一个数字是 offset(偏移量,15),第二个数字是 row_count(行数,10),这与 LIMIT row_count OFFSET offset 的顺序相反。

在 Web 应用程序中实现分页时,LIMIT 和 OFFSET 值通常来自用户输入(例如,单击页码)。使用预处理语句来防止 SQL 注入漏洞是至关重要的。

PDO 示例:

<?php
// Assuming $pdo is a valid PDO connection object
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, ['options' => ['default' => 1, 'min_range' => 1]]);
$itemsPerPage = 10;
// Calculate offset
$offset = ($page - 1) * $itemsPerPage;
// Prepare the statement
// Note: LIMIT/OFFSET parameters need to be bound as integers.
$sql = "SELECT order_id, customer_name FROM Orders ORDER BY order_date DESC LIMIT :limit OFFSET :offset";
$stmt = $pdo->prepare($sql);
// Bind parameters
// PDO::PARAM_INT ensures the values are treated as integers.
$stmt->bindParam(':limit', $itemsPerPage, PDO::PARAM_INT);
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
// Execute and fetch results
$stmt->execute();
$orders = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Display orders...
foreach ($orders as $order) {
echo htmlspecialchars($order['order_id']) . ': ' . htmlspecialchars($order['customer_name']) . '<br>';
}
?>

MySQLi 示例 (面向对象):

<?php
// Assuming $mysqli is a valid mysqli connection object
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, ['options' => ['default' => 1, 'min_range' => 1]]);
$itemsPerPage = 10;
// Calculate offset
$offset = ($page - 1) * $itemsPerPage;
// Prepare the statement
$sql = "SELECT order_id, customer_name FROM Orders ORDER BY order_date DESC LIMIT ? OFFSET ?";
$stmt = $mysqli->prepare($sql);
// Bind parameters (use 'i' for integer)
$stmt->bind_param('ii', $itemsPerPage, $offset);
// Execute and fetch results
$stmt->execute();
$result = $stmt->get_result();
$orders = $result->fetch_all(MYSQLI_ASSOC);
// Close statement
$stmt->close();
// Display orders...
foreach ($orders as $order) {
echo htmlspecialchars($order['order_id']) . ': ' . htmlspecialchars($order['customer_name']) . '<br>';
}
?>

关键要点:

  • 始终验证和清理用于 LIMIT 和 OFFSET 的输入(例如,确保它们是正整数)。
  • 使用预处理语句 (PDO 或 MySQLi) 安全地绑定 LIMIT 和 OFFSET 值。
  • 在使用 LIMIT/OFFSET 进行分页时,务必使用 ORDER BY 子句以确保页面之间结果的一致性和有意义性。