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

用于自动为结果集中的行编号的纯SQL技术,sql,mysql,Sql,Mysql,我正在寻找一种对结果集中的行(而不是表)进行顺序编号的方法。本质上,我从如下查询开始: SELECT id, name FROM people WHERE name = 'Spiewak' ID显然不是真实的序列,例如1、2、3、4。我需要的是结果集中的另一列,它包含这些自动编号。如果必须的话,我愿意使用SQL函数,但我宁愿不使用ANSI规范上的扩展 平台是MySQL,但是如果可能的话,技术应该是跨平台的,因此希望避免非标准扩展。我知道没有ANSI标准的方法来实现这一点 在SQL Server

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

SELECT id, name FROM people WHERE name = 'Spiewak'
ID显然不是真实的序列,例如1、2、3、4。我需要的是结果集中的另一列,它包含这些自动编号。如果必须的话,我愿意使用SQL函数,但我宁愿不使用ANSI规范上的扩展


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

我知道没有ANSI标准的方法来实现这一点

在SQL Server中有一个可以使用的行数函数,在Oracle中有一个ROWNUM伪列


在MySQL中,需要有一个有意义的行号来排序结果。然后你可以这样做:

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

SQLServer有行数覆盖结构来简化这一点,但我不知道MySQL是否有什么特殊的解决方法


因为我在这里的帖子被接受为答案,所以我还想引用Dan Goldstein的回答,这在方法上非常相似,但使用联接而不是子查询,通常会执行得更好

此页面应该为您提供一种标准的SQL方式:


希望这有帮助。

好吧,没有标准的方法

MS SQL Server有行号,MySQL没有

在MySQL中实现这一点的最简单方法是

从测试a中选择a.*,@num:=@num+1b,选择@num:=0d


来源:

中的注释一个效率很低但却是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'

在oracle中,我所知道的唯一一个数据库就是对数据进行子选择

i、 e

基本概念是rownum将根据从内部select返回的结果集进行计算


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

我知道这是一个旧线程,但我刚才正在寻找这个答案。我在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,按p2.id分组似乎就足够了。可以将p2.id的显式顺序添加到查询的末尾,但无论采用哪种方式,我都得到了相同的结果。

最近对这个问题的回答,但我认为窗口函数现在是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'

他可能更喜欢用ROW_NUMBER来排名,但由于他使用的是MySQL/Ansi,这是一个没有实际意义的观点。这很聪明,但性能一定很糟糕。我并不是说有更好的答案,只是对它的第^2页感到不寒而栗。哇!那很聪明。我甚至不知道您可以使用子查询以这种方式定义res字段。我同意性能可能会更好,但如果您仅限于ansi,则必须这样做。有时人们会预先计算这些结果以加快速度。哦,如果你的id列在聚集索引上,那么可能没那么糟糕。至少SQL Server 2000足够聪明,可以缓存和构建以前的结果。此解决方案是ANSI,可以执行-但是-这是一个潜在的维护噩梦问题-排序必须严格,并且可能与条件更改不同步。基本上与我发布的相同,但是,在大多数情况下,联接可能比子查询快。哦,您仍然需要在外部查询上显示order by,否则返回的结果的顺序可能与查询不同。
  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
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'