Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create CTE which uses another CTE as the data to further limit?

Tags:

I have searched this question here but couldn't find it, please redirect me if we already have it on the site.

I'm looking for a way to create CTE which uses another CTE as the data to further limit. I have a CTE which creates a report for me , but I would like to narrow this report with another input using the existing CTE.

I hope my question is clear.

like image 325
curiousBoy Avatar asked Jun 10 '13 20:06

curiousBoy


People also ask

How do I get the CTE difference between two CTEs?

To reference the CTE difference in the second CTE, you treat it as a table: FROM difference. Finally, you group the result by the username, since you don’t want the average for all users. The outer query then simply selects the columns username and average from the CTE average_logged. That way, you get the same result as in the first example:

What is a CTE in SQL?

A CTE is a feature that lets you change how you write your query. No new objects are created on the database. The database will analyse your query and decide on the best way to run it. Because a CTE is mainly used to improve readability and reduce complexity, the database will treat the query in the same way as if it was written as one big query.

What are the rules for CTE query?

1 A CTE must be followed by a single SELECT, INSERT, UPDATE, or DELETE statement that references some or all the CTE columns. 2 Multiple CTE query definitions can be defined in a non recursive CTE. 3 A CTE can reference itself and previously defined CTEs in the same WITH clause 4 We can use only one With Clause in a CTE More items...

Can multiple CTE query definitions be defined in a CTE?

Multiple CTE query definitions can be defined in a non recursive CTE. SELECT DISTINCT, GROUP BY, HAVING, Scalar aggregation, TOP, LEFT, RIGHT, OUTER JOIN (INNER JOIN is allowed) subqueries cannot be used in a recursive CTE query definition.


2 Answers

You can chain 2 (or more) CTE's together.

For example

with ObjectsWithA as
(
  select * from sys.objects
  where name like '%A%'
),
ObjectsWithALessThan100 as
(
  select * from ObjectsWithA
  where object_id < 100
)
select * from ObjectsWithALessThan100;

Or the same example, with more "spelled out" names/aliases:

with ObjectsWithA (MyObjectId , MyObjectName) as
(
  select object_id as MyObjIdAlias , name as MyNameAlias 
  from sys.objects
  where name like '%A%'
),
ObjectsWithALessThan100 as
(
  select * from ObjectsWithA theOtherCte
  where theOtherCte.MyObjectId < 100
)
select lessThan100Alias.MyObjectId , lessThan100Alias.MyObjectName 
from ObjectsWithALessThan100 lessThan100Alias 
order by lessThan100Alias.MyObjectName;
like image 151
DaveShaw Avatar answered Sep 22 '22 02:09

DaveShaw


A CTE can refer to previous CTEs:

with report as (
      <your query here>
     ),
     reportLimited as (
      select *
      from report
      where foo = @bar
    )
select *
from reportLimited

The only rule is that the references have to be sequential. No forward references.

like image 21
Gordon Linoff Avatar answered Sep 19 '22 02:09

Gordon Linoff