如何使用Microsoft SQL Server实现LIMIT?

时间:2009-03-02 19:55:00

标签: sql sql-server migration

我有mysql的这个查询:

select * from table1 LIMIT 10,20

如何使用Microsoft sql执行此操作?

18 个答案:

答案 0 :(得分:110)

启动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

答案 1 :(得分:51)

笨重,但它会起作用。

SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id
IMO,MSSQL遗漏了LIMIT条款是犯罪行为。你不应该做这种愚蠢的解决方法。

答案 2 :(得分:26)

从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,则返回的结果集不符合预期。

答案 3 :(得分:18)

这几乎与我10月份提出的问题重复: Emulate MySQL LIMIT clause in Microsoft SQL Server 2000

如果您使用的是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;

您也可以将其写为common table expression,如@Leon Tayson的answer所示。

答案 4 :(得分:12)

这是我限制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"是您要从表中开始拉出的记录/行号。
IE:如果表1中有40条记录,上面的代码将从第10行开始。

" yy"是要从表中提取的记录/行数。
以前面的例子为基础。
IE:如果表1有40条记录,你开始从第10行拉出并抓住NEXT 10(yy)。
这意味着,上面的代码将从第10行开始,从第10行开始,从第20行结束,从而拉出第10行的记录。

查看有关OFFSET

的更多信息的链接

答案 5 :(得分:12)

SELECT  *
FROM    (
        SELECT  TOP 20
                t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
        FROM    table1 t
        ORDER BY
                field1
        ) t
WHERE   rn > 10

答案 6 :(得分:8)

语法上,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 

答案 7 :(得分:2)

这是我试图避免使用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行之间的数据(而不是搜索整个数据集并限制输出)。

答案 8 :(得分:1)

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;

答案 9 :(得分:1)

这是一个可以在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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

一定要试试。在下面的查询中,您可以查看group by,order by,Skip rows和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

答案 12 :(得分:0)

如果您的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

答案 13 :(得分:0)

  

最好在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]列,并为每一行分配唯一的计数而无需排序,然后再次选择可以提供限制的位置。:)

答案 14 :(得分:0)

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

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

答案 15 :(得分:0)

简便方法

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是必需的

答案 16 :(得分:-2)

如果我没记错的话(自从我用SQL Server轻松过了一段时间)你就可以使用这样的东西:(2005及以上)

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

答案 17 :(得分:-5)

SELECT TOP 10 * FROM table;

相同
SELECT * FROM table LIMIT 0,10;

Here's an article about implementing Limit in MsSQL这是一本很好的阅读,特别是评论。