• I found this a really useful article since I hadn't played much with CTEs or ROW_NUMBER() before. Both of those concepts have suddenly 'clicked' and I really see the benefits of your approach. Just a few comments though, and apologies for being a bit picky:

    Firstly, when you're applying the LastName, Title and City filters your LIKE clause starts with a wildcard - that's probably fine for small tables, but in large tables that's going to cause a table scan which will kill performance. If that's the application requirement then so be it, but for an example like yours I think you'd be better off removing the leading % so as not to encourage this practice. The whole idea of paging through result sets is to enable efficient IO and network bandwidth usage, particularly over large tables.

    Secondly, several paging solutions I have seen do not scale at all well as the number or records in a table increases. Do you have any idea how well SQL Server optimizes the ROW_NUMBER function and how well your solution scales over big tables? I'll do a little investigation of my own when I get a chance, I've got some tables with several million records in which I'd be interested in doing some tests on.