等效于 SQL SERVER 的 MySQL LIMIT 子句

Posted

技术标签:

【中文标题】等效于 SQL SERVER 的 MySQL LIMIT 子句【英文标题】:MySQL LIMIT clause equivalent for SQL SERVER 【发布时间】:2012-02-19 06:06:51 【问题描述】:

我一直在阅读大量关于 SQL SERVER 的 LIMIT 子句的替代方案。令人沮丧的是,他们仍然拒绝适应它。无论如何,我真的无法解决这个问题。我要转换的查询是这样的......

SELECT ID, Name, Price, Image FROM Products ORDER BY ID ASC LIMIT $start_from, $items_on_page

任何帮助将不胜感激,谢谢。

【问题讨论】:

看起来合法。什么错误? ***.com/questions/3128043/… ***.com/questions/3128043/… @user1135440 不是类似的问题。 @Cornel LIMITmysql 中工作。 Zizo47 正在尝试在 SQL Server 中找到等效的语法 - LIMIT 不是吗。 【参考方案1】:

在 SQL Server 2012 中,支持 ANSI 标准 OFFSET / FETCH 语法。我是blogged about this,这里是the official doc(这是ORDER BY 的扩展)。您为 SQL Server 2012 转换的语法将是:

SELECT ID, Name, Price, Image 
  FROM Products 
  ORDER BY ID ASC 
  OFFSET (@start_from - 1) ROWS -- not sure if you need -1
    -- because I don't know how you calculated @start_from
  FETCH NEXT @items_on_page ROWS ONLY;

在此之前,您需要使用各种解决方法,包括ROW_NUMBER() 方法。请参阅this article 和follow-on discussion。如果您不在 SQL Server 2012 上,则不能使用标准语法或 MySQL 的非标准 LIMIT,但可以使用更详细的解决方案,例如:

;WITH o AS
(
    SELECT TOP ((@start_from - 1) + @items_on_page)
         -- again, not sure if you need -1 because I 
         -- don't know how you calculated @start_from
      RowNum = ROW_NUMBER() OVER (ORDER BY ID ASC)
      /* , other columns */
    FROM Products
)
SELECT 
    RowNum
    /* , other columns */
FROM
    o
WHERE
    RowNum >= @start_from
ORDER BY
    RowNum;

还有很多其他方法可以给这只猫剥皮,这不太可能是最有效的,但从语法上讲可能是最简单的。我建议查看我发布的链接以及 cmets 中针对该问题提出的重复建议。

【讨论】:

抱歉,Anon 先生是我。我似乎对正确答案投了反对票。我用了你提到的第二种方法,很有魅力:)【参考方案2】:

对于 SQL Server 2005 和 2008 这是一个示例查询,用于从按 LastName 排序的 Report 表中选择第 11 到 20 行。

SELECT a.* FROM 
(SELECT *, ROW_NUMBER() OVER (ORDER BY LastName) as row FROM Report) a
WHERE a.row > 10 and a.row <= 20

【讨论】:

【参考方案3】:

如果您允许应用程序存储一点状态,您可以只使用TOP items_on_page 来完成此操作。您所做的是存储您检索到的最后一个项目的 ID,并为每个后续查询添加 AND ID &gt; [last ID]。因此,您将分批获得 items_on_page 的项目,每次都从您离开的地方开始。

【讨论】:

嗯,基于实际数据可能是错误的。数据可以一直移动,除非此表中的行永远无法删除。它还假定数据应按 ID 排序,但这并不常见 - 通常数据按字母顺序、相关性或价格或其他用户定义的顺序排序。 @AaronBertrand:他在原始查询中按 ID 排序,看起来是一个分配的递增标识符。 了解,但并非所有读者都有相同的要求或会注意到原始问题中的细微差别。 另外,LIMIT items_on_page 在 SQL Server 中也不起作用。你的意思是TOP【参考方案4】:

试试这个:

SELECT TOP $items_on_page ID, Name, Price, Image 
FROM (SELECT TOP $start_from + $items_on_page - 1 * FROM Products ORDER BY ID) as T 
ORDER BY ID DESC

编辑:解释-

没有绕过子查询,但这是一个优雅的解决方案。 假设您希望每页有10 个项目,从5th 行开始,这将为您提供顶部14 行的底部10 行。本质上是LIMIT 5,10

【讨论】:

我测试了你的查询,但它返回了这个:关键字'FROM'附近的语法不正确 啊,不用担心,刚刚想通了。您的代码效果很好,显然唯一的问题是可能会在项目的最后一页重复一些。非常感谢【参考方案5】:

您可以使用 ROW COUNT :返回受最后一条语句影响的行数。当你不这样做时,你重置 rowcont。

SET ROWCOUNT 100

或 您可以尝试使用 TOP 查询

SELECT TOP 100 * FROM Sometable ORDER BY somecolumn

【讨论】:

这非常适合第一页。需要稍微复杂一点才能获取第二、第三和第 n 页,并且如果您请求第二页并且表只有 80 行,也应该优雅地失败。

以上是关于等效于 SQL SERVER 的 MySQL LIMIT 子句的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 限制的 SQL Server 等效项 [重复]

C# 等效于 SQL Server 中的 IsNull() 函数

SQL Server 的 mysqldump 等效项

SQL Server:删除表级联等效?

MySQL FOUND_ROWS() 方法的 SQL 等效项是啥?

MS-SQL 中是不是有等效于 SHA1() 的方法?