如何在单独的数据集中获取CTE的行数?

| 我确定了一种使用CTE和Row_Number函数从数据库中获取快速分页结果的方法,如下所示...
DECLARE @PageSize INT = 1
DECLARE @PageNumber INT = 2

DECLARE @Customer TABLE (
  ID       INT IDENTITY(1, 1),
  Name     VARCHAR(10),
  age      INT,
  employed BIT)

INSERT INTO @Customer
    (name,age,employed)
SELECT \'bob\',21,1
    UNION ALL
SELECT \'fred\',33,1
    UNION ALL
SELECT \'joe\',29,1
    UNION ALL
SELECT \'sam\',16,1
    UNION ALL
SELECT \'arthur\',17,0;


WITH cteCustomers
     AS ( SELECT
            id,
            Row_Number( ) OVER(ORDER BY Age DESC) AS Row
          FROM   @Customer
          WHERE  employed = 1 
     /*Imagine I\'ve joined to loads more tables with a really complex where clause*/
     )       

SELECT
  name,
  age,
  Total = ( SELECT
              Count( id )
            FROM   cteCustomers )
FROM       cteCustomers
INNER JOIN @Customer cust
  /*This is where I choose the columns I want to read, it returns really fast!*/
  ON cust.id = cteCustomers.id
WHERE      row BETWEEN ( @PageSize * @PageNumber - 1 ) AND ( @PageSize * ( @PageNumber ) )
ORDER      BY row ASC
使用这种技术,即使在复杂的联接和过滤器上,返回的结果也确实非常快。 要执行分页,我需要知道完整CTE返回的总行数。我通过放置一个包含它的列来“绑定”
Total = ( SELECT
              Count( id )
            FROM   cteCustomers )
有没有更好的方法可以将总计返回不同的结果集中而无需将其绑定到列中?因为它是CTE,所以我似乎无法将其纳入第二个结果集中。     
已邀请:
在不先使用临时表的情况下,我将使用CROSS JOIN来减少对COUNT行进行逐行评估的风险 要获得总行数,需要在WHERE上单独进行
WITH cteCustomers
     AS ( SELECT
            id,
            Row_Number( ) OVER(ORDER BY Age DESC) AS Row
          FROM   @Customer
          WHERE  employed = 1 
     /*Imagine I\'ve joined to loads more tables with a really complex where clause*/
     )       

SELECT
  name,
  age,
  Total
FROM       cteCustomers
INNER JOIN @Customer cust
  /*This is where I choose the columns I want to read, it returns really fast!*/
  ON cust.id = cteCustomers.id

CROSS JOIN

(SELECT Count( *) AS Total FROM   cteCustomers ) foo

WHERE      row BETWEEN ( @PageSize * @PageNumber - 1 ) AND ( @PageSize * ( @PageNumber ) )
ORDER      BY row ASC
但是,不能保证如此处所示获得准确的结果: 如何从sql server中的一个sql查询中获取count()和行? 编辑:几句话后。 如何避免交叉联接
WITH cteCustomers
     AS ( SELECT
            id,
            Row_Number( ) OVER(ORDER BY Age DESC) AS Row,
            COUNT(*) OVER () AS Total --the magic for this edit
          FROM   @Customer
          WHERE  employed = 1 
     /*Imagine I\'ve joined to loads more tables with a really complex where clause*/
     )       

SELECT
  name,
  age,
  Total
FROM       cteCustomers
INNER JOIN @Customer cust
  /*This is where I choose the columns I want to read, it returns really fast!*/
  ON cust.id = cteCustomers.id
WHERE      row BETWEEN ( @PageSize * @PageNumber - 1 ) AND ( @PageSize * ( @PageNumber ) )
ORDER      BY row ASC
注意:YMMV的性能取决于2005或2008,Service Pack等 编辑2: SQL Server Central显示了另一种反向ROW_NUMBER的技术。看起来很有用     
@Digiguru 天哪,这真是圣杯!
WITH cteCustomers
AS ( SELECT id,
         Row_Number() OVER(ORDER BY Age DESC) AS Row,
         Row_Number() OVER(ORDER BY id ASC)
            + Row_Number() OVER(ORDER BY id DESC) - 1 AS Total /*<- voodoo here*/
      FROM   @Customer
      WHERE  employed = 1
      /*Imagine I\'ve joined to loads more tables with a really complex where clause*/
   )
SELECT  name,  age,  Total
  /*This is where I choose the columns I want to read, it returns really fast!*/
FROM cteCustomers
INNER JOIN @Customer cust
ON cust.id = cteCustomers.id
WHERE row BETWEEN ( @PageSize * @PageNumber - 1 ) AND ( @PageSize * ( @PageNumber ) )
ORDER BY row ASC
现在很明显。     

要回复问题请先登录注册