我正在开发一个必须与 MS SQL Server 2000 兼容的系统(是的,很糟糕,但请告诉我们仍在使用它的客户)。无论如何,我遇到了这种情况的障碍......
这个表中可以有很多记录(实际上是产品表)。我们的一位客户甚至拥有近 100 万条记录。我正在建立一个网上商店,需要显示该表中的记录。当然,我应该在网络中提供分页,所以我需要一个选项来仅选择从 X 到 Y 的记录。
但是如何以某种方式做到这一点,既高效,又在 SQL Server 2000 中也能工作?
我所知道的 SQL Server 2000 上大表的唯一半可行的解决方案是该模式
SELECT TOP 100 *
FROM products p1
WHERE p1.productID not in (SELECT TOP 200 productID FROM products p2)
这将显示第 201-300 行。
如果需要排序和过滤(通常是这样),您需要确保查询和子查询中的顺序和过滤器相同(否则,结果有点奇怪),就像
SELECT TOP 100 *
FROM products p1
WHERE p1.productID not in (SELECT TOP 200 productID
FROM products p2
WHERE p2.productGroup = 2
ORDER BY p2.productName)
AND p1.productGroup = 2
ORDER BY p1.productName
(这将返回 201-300 产品,其中 ProductGroup 为 2 按名称排序)。
这种方法的缺点是 SQL Server 2000 不支持
TOP @variable
语法,因此上面查询中的 100 和 200 不能轻松参数化。要生成此查询,您必须使用将使用动态 SQL 的 SP,或者在客户端应用程序上编译它,然后按原样将其发送到数据库。
在一个不相关的咆哮中,我一直想知道为什么这在数据库级别上不受支持,例如类似
SELECT ROW 201-300 *
FROM products
WHERE....
因为这样的场景一遍又一遍地出现。
SWeko 有一个很好的答案,这是我的第一个想法。 如果您不想使用子查询,您可以:
SET ROWCOUNT @Y
SELECT *
FROM products p1
WHERE p1.productID > @X
ORDER BY p1.productID
SET ROWCOUNT 0
尽管你必须记住@X,它可能不是整数或单位。
我在寻找类似的解决方案时找到了这个答案:
SELECT
product_name,
list_price
FROM
production.products
ORDER BY
list_price,
product_name
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
完整的解释可以在这里获得。
我们使用了以下技术:
SELECT TOP @top * FROM ...
其中@top等于(Y)。因此,SQL Server 仅选择顶部行,为了获得预期的页面,我们使用了简单的获取而不提取数据(直到 X)