CREATE PROCEDURE Paging_SubQuery (
@Tables varchar(1000),
@PK varchar(100),
@Sort varchar(200) = NULL,
@PageNumber int = 1,
@PageSize int = 10,
@Fields varchar(1000) = '*',
@Filter varchar(1000) = NULL,
@Group varchar(1000) = NULL)
AS
DECLARE @strPageSize varchar(50)
DECLARE @strSkippedRows varchar(50)
DECLARE @strFilter varchar(1000)
DECLARE @strSimpleFilter varchar(1000)
DECLARE @strGroup varchar(1000)
/*Default Sorting*/
IF @Sort IS NULL OR @Sort = ''
	SET @Sort = @PK
SET @Sort = ' ORDER BY ' + @Sort + ' '
/*Default Page Number*/
IF @PageNumber < 1
	SET @PageNumber = 1
/*Set paging variables.*/
SET @strPageSize = CONVERT(varchar(50), @PageSize)
SET @strSkippedRows = CONVERT(varchar(50), @PageSize * (@PageNumber - 1))
/*Set filter & group variables.*/
IF @Filter IS NOT NULL AND @Filter != ''
	BEGIN
		SET @strFilter = ' WHERE ' + @Filter + ' '
		SET @strSimpleFilter = ' AND ' + @Filter + ' '
	END
ELSE
	BEGIN
		SET @strSimpleFilter = ''
		SET @strFilter = ''
	END
IF @Group IS NOT NULL AND @Group != ''
	SET @strGroup = ' GROUP BY ' + @Group + ' '
ELSE
	SET @strGroup = ''
IF @PageNumber = 1  -- In this case we can execute a more efficient query with no subqueries.
	EXEC (
		'SELECT TOP ' + @strPageSize + ' ' + @Fields + ' FROM ' + @Tables +
			@strFilter + @strGroup + @Sort
)
ELSE  -- Execute a structure of subqueries that brings the correct page.
	EXEC (
		'SELECT ' + @Fields + ' FROM ' + @Tables + '  WHERE ' + @PK + ' IN ' + '
			(SELECT TOP ' + @strPageSize + ' ' + @PK + ' FROM ' + @Tables +
			' WHERE ' + @PK + ' NOT IN
				(SELECT TOP ' + @strSkippedRows + ' ' + @PK + ' FROM ' + @Tables +
					@strFilter + @strGroup + @Sort + ') ' +
			@strSimpleFilter +
			@strGroup +
			@Sort + ') ' +
			@strGroup +
			@Sort
)
GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO