question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Question Is it possible to emit nested CTE blocks in a query? (postgres dialect)

Example Here’s a minimal example of a nested CTE query.

with res_cte as (
    select
        account_0.name acct_name,
        (
            with offer_cte as (
                select
                    offer_0.id
                from
                    offer offer_0
                where
                    offer_0.account_id = account_0.id
            )
            select
                array_agg(offer_cte.id)
            from
                offer_cte
        ) as offer_arr
    from
        account account_0
)
select 
    acct_name, offer_arr
from res_cte

In my attempts, the emitted SQL unnests the CTEs which results in an incorrect scope for the offer_0.account_id=account_0.id join

The specific usecase is returning (maybe deeply) joined data as a single json object.

Useful links https://stackoverflow.com/questions/58513337/sqlalchemy-nested-cte-query

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:16 (16 by maintainers)

github_iconTop GitHub Comments

1reaction
zzzeekcommented, Jun 17, 2020

it might not be impossible to do nested CTEs but I would need some simple and straightforward example that can show what they accomplish, as this would drive how the feature would be implemented from an API point of view and how we would describe the use case. at the moment I don’t have plans to work on this but certainly if we can make the case a little more simply and there’s a good reason for this, it’s possibly doable.

0reactions
zzzeekcommented, May 19, 2020

Here’s the thing about CTEs. In SQLAlchemy, you get the same syntactical approach to using a CTE as you do to a subquery, it’s literally the difference between calling cte() or subquery() on the objects. The reason cte() is helpful is because the “subquery” is independent of the rest of the query, can affect planning results and things like that.

but in this case we can take the nested CTE and just turn it into a subquery:

with res_cte as (
    select
        account_0.email acct_email,
        (
            select
                array_agg(post_cte.id)
            from
                (
                select
                    post_0.id
                from
                    post post_0
                where
                    post_0.account_id = account_0.id
            ) post_cte
        ) as post_arr
    from
        account account_0
)
select 
    acct_email, post_arr
from res_cte

if you are “nesting” anyway, there’s not much difference.

another form features the two CTEs as siblings but then you have to do the “correlated subquery” part in a different place which I guess is what you’re trying to avoid:


with post_cte as (
    select
        post_0.id, post_0.account_id
    from
        post post_0
),
res_cte as (
    select
        account_0.email acct_email,
        (
            select
                array_agg(post_cte.id)
            from
                post_cte where post_cte.account_id = account_0.id
        ) as post_arr
    from
        account account_0
)
select 
    acct_email, post_arr
from res_cte

I haven’t myself gotten into the “CTE habit” yet because when you write SQLAlchemy queries you usually can hardly notice if the object your SELECTing from is a cte() or an subquery(). I understand that it does change query planner results though.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Nested Common Table Expressions (i.e. CTE) – Sql Server
Nested CTEs is a scenario where one CTE references another CTE in it. EXAMPLE 1: Below is a basic example of a Nested...
Read more >
Can you create nested WITH clauses for Common Table ...
While not strictly nested, you can use common table expressions to reuse previous queries in subsequent ones.
Read more >
Nested CTEs in Microsoft SQL Server - Steve Stedman
The same concept applies for all of the nested CTEs in a nested CTE query. Any CTE query can access the CTEs declared...
Read more >
How to Write Multiple CTEs in SQL - LearnSQL.com
Using two independent CTEs in one SQL query. Using two CTEs where the second CTE refers to the first. Using two CTEs where...
Read more >
WITH common_table_expression (Transact-SQL) - SQL Server
The recursive CTE definition must contain at least two CTE query definitions, an anchor member and a recursive member.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found