04. juni 2008 - 13:43Der er
5 kommentarer og 1 løsning
Antal rows i WITH xx AS(SELECT)
Jeg bruger følgende procedure til søgning i forumposts og skal returnere antal rows fundet i den første SELECT dvs. PostRN, før den anden SELECT begrænser resultatet så den kun returnere de rækker som skal vises ift. paging.
Antal rows i alt skal returneres som output-variablen @RecCount
Jeg har prøvet med følgende før den anden SELECT, men det virker selvfølgelig ikke:
-- Set total number of rows SELECT @RecCount = @@ROWCOUNT
Kort sagt, hvordan sætter/returnere jeg @RecCount med antallet af records i PostRN, uden at skulle lave den samme SELECT to gange for at tælle det totale antal records?
-----------------
ALTER PROCEDURE [dbo].[Forum_ForumPostsSearch]
@SearchQ varchar, @PageNum INT, @PageSize INT, @RecCount INT OUTPUT
AS
BEGIN
WITH PostRN AS ( SELECT ROW_NUMBER() OVER(ORDER BY ForumPostKEY.RANK DESC, ForumPost.TimeMade DESC) AS RowNum, ForumPostKEY.RANK, [ForumPost].ForumPostID, [ForumPost].ForumPostSubject, [ForumPost].TimeMade
FROM [ForumPost]
INNER JOIN FREETEXTTABLE(ForumPost, (ForumPostBody, ForumPostSubject), @SearchQ) AS ForumPostKEY ON [ForumPost].ForumPostID = ForumPostKEY.[KEY]
WHERE [ForumPost].Deleted = 0 )
-- Add the paging intelligence to select the wanted rows SELECT * FROM PostRN WHERE RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize
Det kan du ikke direkte. En cte skal man ikke tænke på som værende 2 forskellige selects, men blot én query der er skrevet op på en lidt speciel måde. Hvis du vil vide hvor mange rows der er i alt, så må du manuelt udføre denne også:
SELECT COUNT(*) FROM [ForumPost] INNER JOIN FREETEXTTABLE(ForumPost, (ForumPostBody, ForumPostSubject), @SearchQ) AS ForumPostKEY ON [ForumPost].ForumPostID = ForumPostKEY.[KEY]
Det er jo netop IKKE den samme select cer bliver kaldt 2 gange. Forestil dig at cte'en fungerer lige som et view, der kun eksisterer lokalt. Hvis du har lavet et view sådan her:
create view mitView as select * from dinTabel
og så bagefter kalder: select * from mitView. where x = y
Så vil du jo heller ikke ud fra den sidste query kunne få at vide hvor mange rækker der i alt findes i view'et, uden at kalde en select count på view'et.
hmm. Det jeg gør nu er at jeg først finder det totale antal recored (@RecCount) med et select count og så laver samme kald for at lave PostRN, som jeg så til sidst køre en select på, som finder de rækker som skal returneres - er det sådan du mener det skal laves?:
BEGIN
SELECT @RecCount = ( SELECT COUNT(*) FROM [ForumPost]
INNER JOIN FREETEXTTABLE(ForumPost, (ForumPostBody, ForumPostSubject), @SearchQ) AS ForumPostKEY ON [ForumPost].ForumPostID = ForumPostKEY.[KEY]
WHERE [ForumPost].Deleted = 0 )
END
BEGIN
WITH PostRN AS ( SELECT ROW_NUMBER() OVER(ORDER BY ForumPostKEY.RANK DESC, ForumPost.TimeMade DESC) AS RowNum, ForumPostKEY.RANK, [ForumPost].ForumPostID, [ForumPost].ForumPostSubject, [ForumPost].TimeMade
FROM [ForumPost]
INNER JOIN FREETEXTTABLE(ForumPost, (ForumPostBody, ForumPostSubject), @SearchQ) AS ForumPostKEY ON [ForumPost].ForumPostID = ForumPostKEY.[KEY]
WHERE [ForumPost].Deleted = 0 )
-- Add the paging intelligence to select the wanted rows SELECT * FROM PostRN WHERE RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.