Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference one CTE twice?

Tags:

I have a very fat common table expression which includes row numbers so that I can return a paged result set. I also want to return the total number of records that match the query before I page the result set.

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 

Obviously my query above is patchy, but it's just for illustrating my point. I want a page of results AND the total number of matches. How do I do this without having to literally copy and paste the entire 20+ line CTE?

like image 201
Nathan Ridley Avatar asked Jan 26 '10 00:01

Nathan Ridley


People also ask

Can you reference a CTE more than once?

A CTE is similar to a derived table in that it is not stored and lasts only for the duration of the query. Unlike a derived table, a CTE behaves more like an in-line view and can be referenced multiple times in the same query. Using a CTE makes complex queries easier to read and maintain.

How do you use 2 CTE?

After you've defined the first CTE, it is separated from the second one only by the comma, i.e. you write WITH only once. After that, it doesn't matter how many CTEs you define; it's only important that you separate them by comma and start every CTE using its name.

Can I reference a CTE in another CTE?

Not only can you define multiple CTEs and reference them in a single SELECT statement, but you can also have a CTE that references another CTE. In order to do this all you need to do is define the referenced CTE prior to using it. Here is an example where my first CTE is referenced inside the second CTE definition.

Can I reuse CTE?

CTE benefits CTEs can reference the results multiple times throughout the query. By storing the results of the subquery, you can reuse them throughout a larger query.


1 Answers

Don't think you can. From MSDN

A common table expression (CTE) can be thought of as a temporary result set that is defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement.

Emphasis on "single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement."

This might be a situation where you want to use a Temporary Table.

CREATE TABLE #Recs {   ..... } INSERT INTO #Recs select *, row_number() over (order by id) as rownum from ...... 

If you don't know the structure of the table before hand you can use this form to create a temporary table:

select *, row_number() over (order by id) as rownum INTO #Recs from ...... 

You will be able to use the Temporary table in the manner you have described above.

like image 126
Abe Miessler Avatar answered Oct 19 '22 03:10

Abe Miessler