如何跳过sql查询中的前n行

Amb*_*ish 29 sql

我想触发一个查询" SELECT * FROM TABLE",但只从行中选择N+1.有关如何做到这一点的任何想法?

Maj*_*ati 61

用这个:

SELECT *
FROM Sales.SalesOrderHeader 
ORDER BY OrderDate
OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

/sf/answers/1376841581/

  • 另请注意,“新”语法奇怪地具有与 row_number 方法(索引顺序子句)上的 @skip 线性相关的性能损失。另一方面,语法作为纯粹的附加物有很大的好处,因此任何由某些东西生成的以 order 子句结尾的脚本都可以附加此内容。 (3认同)
  • 注意:此查询仅适用于SQL Server 2012及更高版本 (2认同)

dzh*_*zhu 17

SQL Server:

select * from table
except
select top N * from table
Run Code Online (Sandbox Code Playgroud)

Oracle高达11.2:

select * from table
minus
select * from table where rownum <= N

with TableWithNum as (
    select t.*, rownum as Num
    from Table t
)
select * from TableWithNum where Num > N
Run Code Online (Sandbox Code Playgroud)

Oracle 12.1及更高版本(遵循标准ANSI SQL)

select *
from table
order by some_column 
offset x rows
fetch first y rows only
Run Code Online (Sandbox Code Playgroud)

他们可能或多或少地满足您的需求.

没有直接的方法来做你想要的SQL.但是,在我看来,这不是一个设计缺陷.

SQL不应该像这样使用.

在关系数据库中,表表示关系,它是按定义设置的.集合包含无序元素.

另外,不要依赖记录的物理顺序.RDBMS无法保证行顺序.

如果记录的顺序很重要,最好在表中添加一个如"Num"的列,并使用以下查询.这更自然.

select * 
from Table 
where Num > N
order by Num
Run Code Online (Sandbox Code Playgroud)

  • ANSI SQL:“select * from tablename OFFSET n”,在这种情况下也推荐使用 ORDER BY。 (2认同)

Vik*_*ant 12

查询:in

DECLARE @N INT = 5 --Any random number

SELECT * FROM (
        SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RoNum
              , ID --Add any fields needed here (or replace ID by *)
        FROM TABLE_NAME
) AS tbl 
WHERE @N < RoNum
ORDER BY tbl.ID
Run Code Online (Sandbox Code Playgroud)

这将给出表的行,其中rownumber开始于@N + 1.


小智 9

为了在SQL Server中执行此操作,您必须按列对查询进行排序,以便可以指定所需的行.

例:

select * from table order by [some_column] 
offset 10 rows
FETCH NEXT 10 rows only
Run Code Online (Sandbox Code Playgroud)


Tob*_*ias 8

那这个呢:

SELECT * FROM table LIMIT 50 OFFSET 1
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不适用于所有类型的 SQL,因为“LIMIT”和“OFFSET”关键字不是 ANSI 标准的一部分(请参阅[此问题](http://stackoverflow.com/q/1528604/168775) )。 (6认同)

Car*_*edo 7

你想要LINQ中的东西跳过5并取10吗?

SELECT TOP(10) * FROM MY_TABLE  
WHERE ID not in (SELECT TOP(5) ID From My_TABLE);
Run Code Online (Sandbox Code Playgroud)

此方法适用于任何SQL版本.

  • 它当然是关于一个特定的顺序,因为它可能不是你在第一次运行时得到的那些,在第二次运行时被跳过......没有保证你以任何特定的顺序得到它们。尽管可以实现 SQL,因此顺序添加的未更改记录将以相同的顺序返回 - 但你不应该编码假设...... - 但即使添加了一个订单,如果要跳过的数量很高,这种方法也很糟糕 (3认同)
  • 这不是一个好方法!不管怎样,如果两个部分都没有 order 子句,你会得到一个不可预测的结果:随机取 10 个,不包括 5 个随机...... (2认同)
  • 问题不在于任何特定的订单.它是关于从表中跳过第一个N记录.顺便说一下Select不随机,它将orde中的记录首先插入到表中. (2认同)
  • 正如其他人所说,您绝对需要在此处包含 ORDER BY。SELECT 不一定会生成按“首先插入表的位置”排序的记录。 (2认同)

Khu*_*san 6

我知道现在回答查询已经很晚了。但是我有一个与其他解决方案略有不同的解决方案,我认为这些解决方案具有更好的性能,因为在SQL查询中不执行任何比较,仅完成排序。当SKIP值足够大时,您基本上可以看到其相当大的性能改进。

  1. 最佳性能,但仅适用于SQL Server 2012及更高版本。最初来自@Majid Basirati的回答,值得再次提及。

    DECLARE @Skip INT = 2, @Take INT = 2
    
    SELECT * FROM TABLE_NAME
    ORDER BY ID ASC
    OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY
    
    Run Code Online (Sandbox Code Playgroud)
  2. 不如第一个好,但与SQL Server 2005及更高版本兼容。

    DECLARE @Skip INT = 2, @Take INT = 2
    
    SELECT * FROM 
    (
        SELECT TOP (@Take) * FROM 
        (
            SELECT TOP (@Take + @Skip) * FROM TABLE_NAME
            ORDER BY ID ASC
        ) T1
        ORDER BY ID DESC
    ) T2
    ORDER BY ID ASC
    
    Run Code Online (Sandbox Code Playgroud)