Return two result sets when using WITH TempResults

2019-09-19 05:16发布

问题:

I have the following query where I would like to return two result sets. One being the results as a table and the second just returning the number of potential results, or MaxResults.

The last line errors with Invalid object name ResultsTemp. It does not work until I comment out the second last line. It appears I can only use the ResultsTemp once.

DECLARE @StartRow int;
DECLARE @MaxRows int;
set @StartRow = 0;
set @MaxRows = 5;

WITH ResultsTemp AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY FTS.RANK DESC) AS RowId,
    Id, Name FROM tNews
    INNER JOIN CONTAINSTABLE(tNews, *, 'FORMSOF(INFLECTIONAL, hello)') 
        AS FTS ON tNews.Id = FTS.[KEY]
)

SELECT Id, Name, RowId FROM ResultsTemp 
Group By Id, Name, RowId 
Having RowId between @StartRow and (@StartRow + @MaxRows);

select COUNT(*) from ResultsTemp;

thank you

回答1:

Create table #temp
(
    Id int, 
    Name Varchar(100), 
    RowId int
)

DECLARE @StartRow int;
DECLARE @MaxRows int;
set @StartRow = 0;
set @MaxRows = 5;

SELECT ROW_NUMBER() OVER (ORDER BY FTS.RANK DESC) AS RowId,
Id, Name into #temp FROM tNews
INNER JOIN CONTAINSTABLE(tNews, *, 'FORMSOF(INFLECTIONAL, hello)') 
AS FTS ON tNews.Id = FTS.[KEY]

SELECT Id, Name, RowId FROM #temp
Group By Id, Name, RowId 
Having RowId between @StartRow and (@StartRow + @MaxRows);

select COUNT(RowId) from #temp;


回答2:

This can't be done (as far as I'm aware). There's three workarounds, one which allows you to keep as two distinct result sets, and the other two which require merging the results into the same result set (as either an extra row or an extra column).

  1. Instead of a CTE, push the results into a temporary table then query from that.
  2. Merge the count into the actual result set as another row: use a UNION ALL and give the count row suitable values for ID, Name and RowID so you can extract it from the rest of the data
  3. Add the SELECT COUNT(*) into the primary result set as an extra column with a CROSS JOIN or similar.

For this latter, you can do it by changing your primary query to:

SELECT Id, Name, RowId, countTable.totalRows
    FROM ResultsTemp
        CROSS JOIN (SELECT COUNT(*) AS totalRows FROM ResultsTemp) AS countTable
    GROUP BY Id, Name, RowId 
    HAVING RowId BETWEEN @StartRow and (@StartRow + @MaxRows);

I can't vouch for the performance - you'd need to profile.