仅获取MySQL查询的第一行

50

如果我有这样一个查询:

select * from tbl_foo where name = 'sarmen'

这个表中有多个name = sarmen的实例,如何为每一行虚拟分配行号而不必创建一个自动递增列?我在做这件事情时有原因,并且不需要一个自动递增列。如果每一行都通过SQL或者PHP分配一个虚拟行号,那么我随时可以打印出第一行或最后一行。

谢谢。

3个回答

101

要仅返回一行,请使用 LIMIT 1

SELECT *
FROM tbl_foo
WHERE name = 'sarmen'
LIMIT 1

如果没有 ORDER BY 子句,那么说“第一行”或“最后一行”就没有意义。假设您添加了 ORDER BY 子句,则可以按以下方式使用 LIMIT:

  • 要获取第一行,请使用 LIMIT 1
  • 要获取第二行,可以使用具有偏移量的限制:LIMIT 1, 1
  • 要获取最后一行,请将顺序反转(将 ASC 更改为 DESC 或反之),然后使用 LIMIT 1

2
@George Marian:是的,这就是为什么我写了“除非你有一个ORDER BY子句”。 - Mark Byers
2
谢谢,但我想将每一行设置为一个变量。我知道limit子句,但我不是在寻找那个。 - eminem
1
@eminem: 好的,这是你的选择。你应该知道,在仅选择第一行或最后一行(如你在问题中所说)时,使用ORDER BY和LIMIT 1比对所有行进行编号然后筛选要快得多。后者通常会导致表扫描。 - Mark Byers
1
@eminem:这是最低效的查找数据的方法。然而,如果name列上存在索引,你提供的查询可以使用该索引来使得使用name列的查询更加高效。 - OMG Ponies
1
@eminem:OMG Ponies说得对:由于查询中的WHERE子句,结果集可能只会很小,所以我想性能在这里不是问题。如果您想对问题进行实质性的更改,从而得到完全不同的答案,我认为最好创建一个新问题,而不是编辑当前的问题。编辑问题意味着现有的答案将变得毫无意义。 - Mark Byers
显示剩余4条评论

7

您没有说明订单如何确定,但是这将为您在MySQL中提供排名值:

SELECT t.*,
       @rownum := @rownum +1 AS rank
  FROM TBL_FOO t
  JOIN (SELECT @rownum := 0) r
 WHERE t.name = 'sarmen'

然后您可以根据排名值选择您想要的行。

谢谢,这种类型的查询叫什么?我想了解更多关于它的知识。 - eminem
我尝试过这个,但虚拟排名列为空。也许我可以查询并将每行添加到数组中,并获取第0项?(使用PHP) - eminem
@eminem:更新了查询,请现在尝试。至于学习这个——直到MySQL支持分析/排名/窗口函数之前,这是一个技巧。 - OMG Ponies

3
您可以使用以下代码获取包含特定名称的行总数:
SELECT COUNT(*) FROM tbl_foo WHERE name = 'sarmen'

有了计数,现在可以使用以下方法获取第n行:

SELECT * FROM tbl_foo WHERE name = 'sarmen' LIMIT (n - 1), 1

第一个查询中的 COUNT(*) 的结果为 n,其中 1 <= n <= 该查询结果的总行数。

示例:

获取第三行。

SELECT * FROM tbl_foo WHERE name = 'sarmen' LIMIT 2, 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接