在匹配整行时,在select语句上获取行号

时间:2016-10-10 12:08:21

标签: sql sql-server sql-server-2008

我正在尝试获取行的行号。由于该表没有任何id列,因此我使用ROW_NUMBER()而没有任何订单,如下所示。

SELECT 
    ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS SNO, * 
FROM [table1] 

现在的挑战是我需要找到一个条件的行,它只是一个带有where子句但带有原始行号的select语句。

SELECT TOP 1 * 
FROM table1 
WHERE [Total Sales] = 2555

此语句返回单个记录。我试图使用INTERSECT来组合两个语句以获得带行号的结果。

SELECT 
    ROW_NUMBER() OVER (ORDER BY (SELECT 100)) AS SNO, * 
FROM [table1] 

INTERSECT 

SELECT TOP 1 *
FROM table1
WHERE [Total Sales] = 2555

当然,由于列数不同,这会引发错误。那么获取实际行号的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

运行此查询时:

SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS SNO, t.*
FROM [table1] t;

SNO不稳定。这意味着多次运行相同的查询可能会返回不同的数字。 SQL中的排序不是稳定。这意味着当查询多次运行时,相同的键可以是任意顺序。为什么? SQL表和结果集表示无序集。没有什么可以基于稳定的排序。

对您的问题的简单回答是使用子查询:

SELECT t.*
FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS SNO, t.*
      FROM [table1] t
     ) t
WHERE [Total Sales] = 2555;

但是,真正的答案是,如果要将此值用于多个查询,则应使用多列来创建稳定排序。

答案 1 :(得分:1)

SQL没有初始"行号"对于条目。显示的表顺序全部基于查询结果。如果您希望按顺序将它们保存到数据库中,则可以添加一个时间戳,该时间戳由触发器生成并在插入时附加到该行。然后使用这个时间夯实你可以按它排序。

如果没有我的主键,那么主键是什么?