在主查询中包括结果计数?

Nis*_*ant 5 sql-server count

目前我们执行两个查询以使用分页过滤器获取计数和结果。虽然我们可以轻松地将这两者结合到一个网络调用中(使用 sql 分隔符),但有没有办法在遵循DRY原则的单个查询中做到这一点?

-- count    
SELECT COUNT(*) FROM table;

-- result with pagination
SELECT *
FROM (SELECT ROW_NUMBER() OVER (ORDER BY tbl.idn) AS row, * FROM tbl)_tbl
WHERE row >= 1 AND row <= 10;
Run Code Online (Sandbox Code Playgroud)

维护两个查询真的很有挑战性——单个查询减少了维护开销。

Paw*_*ajs 5

您可以尝试创建一个存储过程并从应用程序中调用它。

CREATE PROCEDURE [dbo].[getPage] 
AS
BEGIN
    DECLARE @cnt INT = (SELECT COUNT(*) FROM table)

    SELECT *, [cnt] = @cnt
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY tbl.idn) AS row, * FROM tbl)_tbl
    WHERE row >= 1 AND row <= 10;
END
Run Code Online (Sandbox Code Playgroud)

或者您可以使用子查询:

CREATE PROCEDURE [dbo].[getPage] 
AS
BEGIN
    SELECT *, [cnt] = (SELECT COUNT(*) FROM table)
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY tbl.idn) AS row, * FROM tbl)_tbl
    WHERE row >= 1 AND row <= 10;
END
Run Code Online (Sandbox Code Playgroud)

编辑。

更好的是,您可以使用OFFSET FETCH子句进行分页目的。您将获得更清晰的代码和更高的性能(此处没有窗口函数)。例如像这样的东西:

CREATE PROCEDURE [dbo].[getPage] 
AS
BEGIN
    DECLARE @cnt INT = (SELECT COUNT(*) FROM table)

    SELECT *, [cnt] = @cnt
    FROM tbl
    ORDER BY idn
    OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;
END
Run Code Online (Sandbox Code Playgroud)

或者使用子查询:

CREATE PROCEDURE [dbo].[getPage] 
AS
BEGIN
    SELECT *, [cnt] = (SELECT COUNT(*) FROM table)
    FROM tbl
    ORDER BY idn
    OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;
END
Run Code Online (Sandbox Code Playgroud)

子查询和变量方法之间没有显着差异。更多的是关于符号。SQL Server 做几乎相同的工作(额外的“无成本”嵌套循环)。在这种特殊情况下,我更喜欢避免窗口函数(可能的 Table Spool - 对 tempdb 的额外影响)。