0

考虑下表:

rowid   |   text    |   group
1       |   a       |   1
2       |   b       |   2
3       |   c       |   2
4       |   d       |   3
5       |   e       |   4
6       |   f       |   1
7       |   g       |   1
8       |   h       |   4
9       |   j       |   5
10      |   k       |   2
11      |   i       |   3
12      |   l       |   3

现在想象我想要 6 的行号rowid(用于例如分页)。由于它是自动递增的,因此仅选择非常简单where rowid = 6,但在这种情况下,我想知道它在组 1 中的行号。

显然,在这样一个小例子(它是第 2 行)中,通过肉眼很容易做到这一点。

第 1 行将是rowid = 1. 第 2 行将是rowid = 6. 第 3 行将是rowid = 7.

我的第一个想法是这样的:

SELECT
    tmp.rowid,
    tmp.text,
    tmp.group,
    tmp.row_number
FROM
    (
        SELECT
            `rowid`,
            `text`,
            `group`,
            (@rowNumber := @rowNumber + 1) as `row_number`
        FROM
            `my_table`,
            (SELECT @rowNumber := 0) as `r`
        WHERE
            `group` = 1
        ORDER BY
            `rowid` DESC
    ) as `tmp`
WHERE
    tmp.rowid = 6

这将给出正确的结果(在 中row_number),但在一个大表(半百万条记录)上,这将在快速服务器上花费 2.5 秒,因为它必须首先收集所有 500,000 个条目,然后选择行 id 6。

我应该怎么做才能让它更快/更好?

4

1 回答 1

1

解决方案其实很简单。

SQL

SELECT
    COUNT(`rowid`) as `row_number`
FROM
    `my_table`
WHERE
    `group` = 1
AND
    `rowid` >= 6

笔记

您需要有一行具有递增值(例如时间戳、递增 ID 等)。

在这里,我们将原始转换ORDER BY rowid DESCWHERErowid >= '6'。如果你使用ORDER BY升序,你会想要使用<=

查询耗时 0.00002 秒,并返回正确的行号(in row_number)。如果您想要textandgroup列,则必须将其设为子查询或进行额外的查询以选择WHERE rowid = 6.

于 2012-12-18T16:10:36.930 回答