用于在结果集中自动编号行的纯SQL技术

时间:2008-10-14 18:20:52

标签: sql mysql

我正在寻找一种方法来顺序编号结果集(不是表格)中的行。从本质上讲,我开始使用如下查询:

SELECT id, name FROM people WHERE name = 'Spiewak'

id s显然不是真正的序列(例如1, 2, 3, 4)。我需要的是结果集中的另一列包含这些自动编号。如果必须的话,我愿意使用SQL函数,但我宁愿不使用ANSI规范的扩展。

平台是MySQL,但是如果可能的话,该技术应该是跨平台的(因此希望避免非标准的扩展)。

10 个答案:

答案 0 :(得分:9)

要获得有意义的行号,您需要订购结果。然后你可以做这样的事情:

SELECT id, name
    , (SELECT COUNT(*) FROM people p2 WHERE name='Spiewak' AND p2.id <= p1.id) AS RowNumber
FROM people p1
WHERE name = 'Spiewak'
ORDER BY id

请注意,子查询的WHERE子句需要匹配WHERE子句或主查询中的主键和主查询的ORDER BY。

SQL Server有ROW_NUMBER()OVER构造来简化这一点,但我不知道MySQL是否有任何特殊的解决方法。


由于我在这里的帖子被接受为答案,我想也想出Dan Goldstein的回答,这在方法上非常相似,但使用JOIN而不是子查询,并且通常会表现得更好

答案 1 :(得分:9)

AFAIK,没有“标准”的方式。

MS SQL Server有row_number(),MySQL没有。

在MySQL中执行此操作的最简单方法是

SELECT a.*, @num := @num + 1 b from test a, (SELECT @num := 0) d;

来源:http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql/

中的评论

答案 2 :(得分:8)

一个非常低效的想法,但是ANSI SQL将计算id匹配相同条件的行数。我没有测试过这个SQL,它可能不会起作用,但是类似于:

SELECT id, name, sub.lcount
FROM people outer
JOIN (SELECT id, COUNT(id) lcount FROM people WHERE name = 'Spiewak' AND id < outer.id GROUP BY id) sub on outer.id = sub.id
WHERE name = 'Spiewak'

答案 3 :(得分:2)

我知道没有ANSI标准的方法可以做到这一点。

在SQL Server中,您有一个可以使用的ROW_NUMBER()函数,在Oracle中,有一个ROWNUM伪列。

在MySQL中,有this technique

答案 4 :(得分:2)

此页面应该为您提供标准的SQL方法:

http://www.sqlteam.com/article/returning-a-row-number-in-a-query

希望这有帮助。

答案 5 :(得分:2)

SELECT @i:=@i+1 AS iterator, t.*
FROM tablename t,(SELECT @i:=0) foo

答案 6 :(得分:2)

在oracle中,我知道你想要做的唯一数据库是对数据进行子选择

select rownum, id , blah, blah
from  (
select id, name FROM people WHERE name = 'Spiewak'
)

基本概念是将对内部选择返回的结果集评估rownum。

我希望这可能会为您指出一个可以使用的解决方案。

答案 7 :(得分:1)

我知道这是一个老话题,但我刚才正在寻找这个答案。我在MySQL中尝试过Dan Goldstein的查询,但它没有按照书面形式工作,因为'outer'是一个保留字。然后,我注意到它仍在使用子查询。

所以,我想出了一个使用JOIN的版本,但没有子查询:

  SELECT SUM(IF(p1.id > p2.id, 0, 1)) AS `row`, p2.id, p2.name
  FROM people p1 JOIN people p2 ON p1.name = p2.name
  WHERE p1.name = 'Spiewak'
  GROUP BY p2.id

这在MySQL 5.1中对我有用。对于MySQL,它似乎足以支持GROUP BY p2.id.显式ORDER BY p2.id可以添加到查询的末尾,但无论哪种方式我都得到相同的结果。

答案 8 :(得分:0)

最近对问题的回答,但我相信窗口函数现在是 ANSI SQL 的标准,或者至少是大多数当前的 SQL 风格。因此,请使用 ROW_NUMBER() 函数。

SELECT
    p.ROW_NUMBER() over (order by id) as 'row_id',
    p.id as 'id',
    p.name as 'name'
FROM
    people p
WHERE
    p.name = 'Spiewak'

答案 9 :(得分:-1)

对于SQL Server,请查看RANK函数。