25

我有一个非常胖的公用表表达式,其中包括行号,以便我可以返回分页结果集。我还想在分页结果集之前返回与查询匹配的记录总数。

with recs as (select *, row_number() over (order by id) as rownum from ......)
select * from recs where rownum between @a and @b .... select count(*) from recs

显然我上面的查询是不完整的,但这只是为了说明我的观点。我想要一页结果和匹配的总数。我如何做到这一点,而不必从字面上复制和粘贴整个 20+ 行 CTE?

4

5 回答 5

20

不要以为你可以。来自MSDN

可以将公用表表达式 (CTE) 视为在单个 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集。

强调“单个 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句”。

这可能是您想要使用临时表的情况。

CREATE TABLE #Recs
{
  .....
}
INSERT INTO #Recs
select *, row_number() over (order by id) as rownum from ......

如果你事先不知道表的结构,你可以使用这个表格来创建一个临时表:

select *, row_number() over (order by id) as rownum INTO #Recs from ......

您将能够以上述方式使用临时表。

于 2010-01-26T00:07:42.537 回答
19

您可以使用逗号创建引用上述 CTE 的多个 CTE。

只是为了说明我的意思:

with recs as (
select 
    *, 
    row_number() over (order by id) as rownum from ......
    ),
counts as (
    select count(*) as totalrows from recs
)
select recs.*,count.totalrows
from recs
cross apply counts 
where rownum between @a and @b .... 

这不是一个好的解决方案。

我发现在不计算记录的情况下计算 CTE 中的总计数的最佳解决方案在本文中进行了描述。

DECLARE @startRow INT; SET @startrow = 50;
WITH cols
AS
(
    SELECT table_name, column_name, 
        ROW_NUMBER() OVER(ORDER BY table_name, column_name) AS seq, 
        ROW_NUMBER() OVER(ORDER BY table_name DESC, column_name desc) AS totrows
    FROM [INFORMATION_SCHEMA].columns
)
SELECT table_name, column_name, totrows + seq -1 as TotRows
FROM cols
WHERE seq BETWEEN @startRow AND @startRow + 49
ORDERBY seq
于 2010-01-26T00:21:56.380 回答
4

您可以附加一个包含总行数的字段,当然它会在每一行上

select recs.*,totalrows = (select count(0) from recs) 
from recs
于 2012-08-02T15:58:02.223 回答
1

这是最好的:

;WITH recs AS
(SELECT a,b,c,
      row_number() over (
                         ORDER BY id) AS RowNum,
                   row_number() over () AS RecordCount
FROM ......)
SELECT a,b,c,rownum,RecordCount FROM recs
WHERE rownum BETWEEN @a AND @b
于 2016-04-27T11:53:05.587 回答
1

这就是我们在生产环境中处理分页(暂时没有会话管理)的方式。按预期执行。

DECLARE
   @p_PageNumberRequested  int = 1,
      -- Provide -1 to retreive all pages with all the rows.
   @p_RowsPerPage          int = 25

;WITH Numbered AS (
SELECT
   ROW_NUMBER() OVER (ORDER BY YourOrdering) AbsoluteRowNumber
,  COUNT(1) OVER () TotalRows
,  YourColumns
FROM
   YourTable
),
Paged AS (
SELECT
   (AbsoluteRowNumber - 1) / @p_RowsPerPage + 1 PageNumber,
   *
FROM
   Numbered)
SELECT
   ROW_NUMBER() OVER(PARTITION BY PageNumber ORDER BY AbsoluteRowNumber) RowNumberOnPage,
   *
FROM
   Paged
WHERE
      PageNumber = @p_PageNumberRequested
   OR
      @p_PageNumberRequested = -1
ORDER BY 
   AbsoluteRowNumber
于 2017-01-24T08:57:27.947 回答