我有一个非常胖的公用表表达式,其中包含行号,以便我可以返回分页结果集。我还希望在分页结果集之前返回与查询匹配的记录总数。
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的情况下完成此操作?
答案 0 :(得分:19)
不要以为你可以。来自MSDN
公用表表达式(CTE)可以 被认为是临时结果集 这是在执行中定义的 单个SELECT,INSERT的范围, 更新,删除或创建视图 言。
强调“单个SELECT,INSERT,UPDATE,DELETE或CREATE VIEW语句。”
这可能是您想要使用Temporary Table。
的情况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 ......
您将能够以上述方式使用临时表。
答案 1 :(得分: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 ....
这不是一个好的解决方案。
this article中描述了我发现在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
答案 2 :(得分:4)
你可以追加一个总行数的字段,当然它会在每一行
select recs.*,totalrows = (select count(0) from recs)
from recs
答案 3 :(得分: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
答案 4 :(得分: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