如何用SQL Server实现LIMIT?

发布于 2024-07-14 00:35:32 字数 124 浏览 6 评论 0原文

我使用 MySQL 进行此查询:

select * from table1 LIMIT 10,20

How can I do this with SQL Server?

I have this query with MySQL:

select * from table1 LIMIT 10,20

How can I do this with SQL Server?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

最单纯的乌龟 2024-07-21 00:35:33

如果我没记错的话(自从我接触 SQL Server 以来已经有一段时间了)你也许可以使用这样的东西:(2005 年及以上)

SELECT
    *
   ,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20

If i remember correctly (it's been a while since i dabbed with SQL Server) you may be able to use something like this: (2005 and up)

SELECT
    *
   ,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20
忘你却要生生世世 2024-07-21 00:35:32

从 SQL SERVER 2005 开始,您可以执行此操作...

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 10 AND 20;

或者对于 2000 及以下版本执行类似操作...

SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC

Starting SQL SERVER 2005, you can do this...

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 10 AND 20;

or something like this for 2000 and below versions...

SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC
醉生梦死 2024-07-21 00:35:32

从 SQL SERVER 2012 开始,您可以使用 OFFSET FETCH 子句:

USE AdventureWorks;
GO
SELECT SalesOrderID, OrderDate
FROM Sales.SalesOrderHeader 
ORDER BY SalesOrderID
    OFFSET 10 ROWS
    FETCH NEXT 10 ROWS ONLY;
GO

http://msdn.microsoft.com/en-us/library/ms188385(v=sql.110).aspx

当排序依据不唯一时,这可能无法正常工作。

如果将查询修改为ORDER BY OrderDate,则返回的结果集与预期不符。

Starting with SQL SERVER 2012, you can use the OFFSET FETCH Clause:

USE AdventureWorks;
GO
SELECT SalesOrderID, OrderDate
FROM Sales.SalesOrderHeader 
ORDER BY SalesOrderID
    OFFSET 10 ROWS
    FETCH NEXT 10 ROWS ONLY;
GO

http://msdn.microsoft.com/en-us/library/ms188385(v=sql.110).aspx

This may not work correctly when the order by is not unique.

If the query is modified to ORDER BY OrderDate, the result set returned is not as expected.

↙厌世 2024-07-21 00:35:32

这就是我在 MS SQL Server 2012 中限制结果的方法:

SELECT * 
FROM table1
ORDER BY columnName
  OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY

注意:OFFSET 只能与 ORDER BY 一起使用或串联使用。

解释一下代码行 OFFSET xx ROWS FETCH NEXT yy ROW ONLY

xx 是您要从表中开始提取的记录/行号,即:如果有表 1 中有 40 条记录,上面的代码将从第 10 行开始提取。

yy 是您要从表中提取的记录/行数。

在上一个示例的基础上构建:如果表 1 有 40 条记录,并且您开始从第 10 行拉取并获取下一组 10 条记录 (yy)。
这意味着,上面的代码将从表 1 中从第 10 行开始到第 20 行拉出记录。从而拉出第 10 - 20 行。

查看有关 偏移

This is how I limit the results in MS SQL Server 2012:

SELECT * 
FROM table1
ORDER BY columnName
  OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY

NOTE: OFFSET can only be used with or in tandem to ORDER BY.

To explain the code line OFFSET xx ROWS FETCH NEXT yy ROW ONLY

The xx is the record/row number you want to start pulling from in the table, i.e: If there are 40 records in table 1, the code above will start pulling from row 10.

The yy is the number of records/rows you want to pull from the table.

To build on the previous example: If table 1 has 40 records and you began pulling from row 10 and grab the NEXT set of 10 (yy).
That would mean, the code above will pull the records from table 1 starting at row 10 and ending at 20. Thus pulling rows 10 - 20.

Check out the link for more info on OFFSET

烧了回忆取暖 2024-07-21 00:35:32

这几乎与我十月份提出的问题重复:
在 Microsoft SQL Server 2000 中模拟 MySQL LIMIT 子句

您使用的是Microsoft SQL Server 2000,没有好的解决方案。 大多数人不得不使用 IDENTITY 主键在临时表中捕获查询结果。 然后使用 BETWEEN 条件查询主键列。

如果您使用的是 Microsoft SQL Server 2005 或更高版本,则可以使用 ROW_NUMBER() 函数,这样您可以获得相同的结果,但可以避免使用临时表。

SELECT t1.*
FROM (
    SELECT ROW_NUMBER OVER(ORDER BY id) AS row, t1.*
    FROM ( ...original SQL query... ) t1
) t2
WHERE t2.row BETWEEN @offset+1 AND @offset+@count;

您还可以将其编写为公用表表达式,如@所示Leon Tayson 的答案

This is almost a duplicate of a question I asked in October:
Emulate MySQL LIMIT clause in Microsoft SQL Server 2000

If you're using Microsoft SQL Server 2000, there is no good solution. Most people have to resort to capturing the result of the query in a temporary table with a IDENTITY primary key. Then query against the primary key column using a BETWEEN condition.

If you're using Microsoft SQL Server 2005 or later, you have a ROW_NUMBER() function, so you can get the same result but avoid the temporary table.

SELECT t1.*
FROM (
    SELECT ROW_NUMBER OVER(ORDER BY id) AS row, t1.*
    FROM ( ...original SQL query... ) t1
) t2
WHERE t2.row BETWEEN @offset+1 AND @offset+@count;

You can also write this as a common table expression as shown in @Leon Tayson's answer.

司马昭之心 2024-07-21 00:35:32
SELECT TOP 10 * FROM table;

相同

SELECT * FROM table LIMIT 0,10;

一篇关于在 MsSQL 中实现 Limit 的文章 读起来很好,特别是评论。

SELECT TOP 10 * FROM table;

Is the same as

SELECT * FROM table LIMIT 0,10;

Here's an article about implementing Limit in MsSQL Its a nice read, specially the comments.

小嗷兮 2024-07-21 00:35:32
SELECT  *
FROM    (
        SELECT  TOP 20
                t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
        FROM    table1 t
        ORDER BY
                field1
        ) t
WHERE   rn > 10
SELECT  *
FROM    (
        SELECT  TOP 20
                t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
        FROM    table1 t
        ORDER BY
                field1
        ) t
WHERE   rn > 10
初熏 2024-07-21 00:35:32

从语法上讲,MySQL LIMIT 查询是这样的:

SELECT * FROM table LIMIT OFFSET, ROW_COUNT

这可以翻译成 Microsoft SQL Server,就像

SELECT * FROM 
(
    SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table
) a
WHERE rnum > OFFSET

现在您的查询 select * from table1 LIMIT 10,20 将如下所示:

SELECT * FROM 
(
    SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table1
) a
WHERE rnum > 10 

Syntactically MySQL LIMIT query is something like this:

SELECT * FROM table LIMIT OFFSET, ROW_COUNT

This can be translated into Microsoft SQL Server like

SELECT * FROM 
(
    SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table
) a
WHERE rnum > OFFSET

Now your query select * from table1 LIMIT 10,20 will be like this:

SELECT * FROM 
(
    SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table1
) a
WHERE rnum > 10 
一杆小烟枪 2024-07-21 00:35:32

简单的方法

MYSQL:

SELECT 'filds' FROM 'table' WHERE 'where' LIMIT 'offset','per_page'

MSSQL:

SELECT 'filds' FROM 'table' WHERE 'where' ORDER BY 'any' OFFSET 'offset' 
ROWS FETCH NEXT 'per_page' ROWS ONLY

ORDER BY 是强制的

Easy way

MYSQL:

SELECT 'filds' FROM 'table' WHERE 'where' LIMIT 'offset','per_page'

MSSQL:

SELECT 'filds' FROM 'table' WHERE 'where' ORDER BY 'any' OFFSET 'offset' 
ROWS FETCH NEXT 'per_page' ROWS ONLY

ORDER BY is mandatory

┈┾☆殇 2024-07-21 00:35:32

这是我尝试避免使用 MS Server 的原因之一……但无论如何。 有时你只是没有选择(是的!我必须使用过时的版本!!)。

我的建议是创建一个虚拟表:

从:

SELECT * FROM table

到:

CREATE VIEW v_table AS    
    SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table

然后只需查询:

SELECT * FROM v_table WHERE row BETWEEN 10 AND 20

如果添加或删除字段,“行”会自动更新。

此选项的主要问题是 ORDER BY 已修复。 因此,如果您想要不同的顺序,则必须创建另一个视图。

更新

这种方法还有另一个问题:如果您尝试过滤数据,它将无法按预期工作。 例如,如果您这样做:

SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20

WHERE 将仅限于第 10 到 20 行中的那些数据(而不是搜索整个数据集并限制输出)。

This is one of the reasons I try to avoid using MS Server... but anyway. Sometimes you just don't have an option (yei! and I have to use an outdated version!!).

My suggestion is to create a virtual table:

From:

SELECT * FROM table

To:

CREATE VIEW v_table AS    
    SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table

Then just query:

SELECT * FROM v_table WHERE row BETWEEN 10 AND 20

If fields are added, or removed, "row" is updated automatically.

The main problem with this option is that ORDER BY is fixed. So if you want a different order, you would have to create another view.

UPDATE

There is another problem with this approach: if you try to filter your data, it won't work as expected. For example, if you do:

SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20

WHERE becomes limited to those data which are in the rows between 10 and 20 (instead of searching the whole dataset and limiting the output).

半岛未凉 2024-07-21 00:35:32

SQL 中不存在 LIMIT 关键字。 如果您只需要有限数量的行,则应该使用类似于 LIMIT 的 TOP 关键字。

In SQL there's no LIMIT keyword exists. If you only need a limited number of rows you should use a TOP keyword which is similar to a LIMIT.

錯遇了你 2024-07-21 00:35:32

一定要试。 在下面的查询中,您可以看到分组依据、排序依据、跳过行和限制行。

select emp_no , sum(salary_amount) from emp_salary
Group by emp_no 
ORDER BY emp_no 
OFFSET 5 ROWS       -- Skip first 5 
FETCH NEXT 10 ROWS ONLY; -- limit to retrieve next 10 row after skiping rows

Must try. In below query, you can see group by, order by, Skip rows, and limit rows.

select emp_no , sum(salary_amount) from emp_salary
Group by emp_no 
ORDER BY emp_no 
OFFSET 5 ROWS       -- Skip first 5 
FETCH NEXT 10 ROWS ONLY; -- limit to retrieve next 10 row after skiping rows
猛虎独行 2024-07-21 00:35:32

这是一种适用于 SQL2000 的多步骤方法。

-- Create a temp table to hold the data
CREATE TABLE #foo(rowID int identity(1, 1), myOtherColumns)

INSERT INTO #foo (myColumns) SELECT myData order By MyCriteria

Select * FROM #foo where rowID > 10

This is a multi step approach that will work in SQL2000.

-- Create a temp table to hold the data
CREATE TABLE #foo(rowID int identity(1, 1), myOtherColumns)

INSERT INTO #foo (myColumns) SELECT myData order By MyCriteria

Select * FROM #foo where rowID > 10
梦言归人 2024-07-21 00:35:32
SELECT 
    * 
FROM 
    (
        SELECT 
            top 20              -- ($a) number of records to show
            * 
        FROM
            (
                SELECT 
                    top 29      -- ($b) last record position
                    * 
                FROM 
                    table       -- replace this for table name (i.e. "Customer")
                ORDER BY 
                    2 ASC
            ) AS tbl1 
        ORDER BY 
            2 DESC
    ) AS tbl2 
ORDER BY 
    2 ASC;

-- Examples:

-- Show 5 records from position 5:
-- $a = 5;
-- $b = (5 + 5) - 1
-- $b = 9;

-- Show 10 records from position 4:
-- $a = 10;
-- $b = (10 + 4) - 1
-- $b = 13;

-- To calculate $b:
-- $b = ($a + position) - 1

-- For the present exercise we need to:
-- Show 20 records from position 10:
-- $a = 20;
-- $b = (20 + 10) - 1
-- $b = 29;
SELECT 
    * 
FROM 
    (
        SELECT 
            top 20              -- ($a) number of records to show
            * 
        FROM
            (
                SELECT 
                    top 29      -- ($b) last record position
                    * 
                FROM 
                    table       -- replace this for table name (i.e. "Customer")
                ORDER BY 
                    2 ASC
            ) AS tbl1 
        ORDER BY 
            2 DESC
    ) AS tbl2 
ORDER BY 
    2 ASC;

-- Examples:

-- Show 5 records from position 5:
-- $a = 5;
-- $b = (5 + 5) - 1
-- $b = 9;

-- Show 10 records from position 4:
-- $a = 10;
-- $b = (10 + 4) - 1
-- $b = 13;

-- To calculate $b:
-- $b = ($a + position) - 1

-- For the present exercise we need to:
-- Show 20 records from position 10:
-- $a = 20;
-- $b = (20 + 10) - 1
-- $b = 29;
策马西风 2024-07-21 00:35:32

如果您的 ID 是唯一标识符类型或表中的 ID 未排序,则必须执行以下操作。

select * from
(select ROW_NUMBER() OVER (ORDER BY (select 0)) AS RowNumber,* from table1) a
where a.RowNumber between 2 and 5

代码将是

select * from limit 2,5

If your ID is unique identifier type or your id in table is not sorted you must do like this below.

select * from
(select ROW_NUMBER() OVER (ORDER BY (select 0)) AS RowNumber,* from table1) a
where a.RowNumber between 2 and 5

The code will be

select * from limit 2,5
若水微香 2024-07-21 00:35:32

最好在 MSSQLExpress 2017 中使用它。

SELECT * FROM
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;

。--给出一个列 [Count] 并为每一行分配一个唯一的计数,而无需订购某些内容,然后再次重新选择可以提供限制的位置..:)

better use this in MSSQLExpress 2017.

SELECT * FROM
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;

--Giving a Column [Count] and assigning every row a unique counting without ordering something then re select again where you can provide your limits.. :)

纵情客 2024-07-21 00:35:32

获得结果的可能方法之一如下,希望这会有所帮助。

declare @start int
declare @end int
SET @start = '5000';  -- 0 , 5000 ,
SET @end = '10000'; -- 5001, 10001
SELECT * FROM ( 
  SELECT TABLE_NAME,TABLE_TYPE, ROW_NUMBER() OVER (ORDER BY TABLE_NAME) as row FROM information_schema.tables
 ) a WHERE a.row > @start and a.row <= @end

One of the possible way to get result as below , hope this will help.

declare @start int
declare @end int
SET @start = '5000';  -- 0 , 5000 ,
SET @end = '10000'; -- 5001, 10001
SELECT * FROM ( 
  SELECT TABLE_NAME,TABLE_TYPE, ROW_NUMBER() OVER (ORDER BY TABLE_NAME) as row FROM information_schema.tables
 ) a WHERE a.row > @start and a.row <= @end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文