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.

Nested subqueries with aliased queries/tables

See original GitHub issue

Describe your question I’m trying to do multi-level nested query, but have some troubles I need to unnest several arrays in json fields and select some of them

Example

  • table is check, it has id (int) and response (json) fields
  • json example (contents of response column):
{
  "Results": [
    {
      "Name": "FooBar",
      "Field": "SomeValue"
    },
    {
      "Name": "SpamEggs",
      "Field": "AnotherValue"
    }
  ]
}

Here’s simplified SQL example which I’m trying to achieve:

SELECT result_elem -> 'Field' as field
FROM "check" AS check_, json_array_elements(
    (
      SELECT check_inside.response -> 'Results'
      FROM "check" as check_inside
      WHERE check_inside.id = check_.id
    )
) AS result_elem
WHERE result_elem ->> 'Name' = 'FooBar';

at first I’m trying to implement inner subquery

python code:

from sqlalchemy import func
from sqlalchemy.orm import aliased
from sqlalchemy.dialects import postgresql

check_inside = aliased(Check, name="check_inside")
check_ = aliased(Check, name="check_")

q_result_elems = session.query(
    check_inside.response["Results"],
).filter(
    check_inside.id == check_.id,
)
subq_result_elems = q_result_elems.subquery(name="subq_result_elems")

print(str(q_result_elems.statement.compile(compile_kwargs={"literal_binds": True}, dialect=postgresql.dialect())))

prints this:

SELECT check_inside.response -> 'Results' AS anon_1 
FROM "check" AS check_inside, "check" AS check_ 
WHERE check_inside.id = check_.id

it already differs on the FROM line then I’m completely lost. this is kinda pseudo-code, which doesn’t work at all:

q_foobar_fields = session.query(
    subq_result_elems.op("->")("Field").label("field"),
).select_from(
    check_,
    func.json_array_elements(
        subq_result_elems,
    ).label("result_elem")
).filter(
    subq_result_elems.op("->>")("Name") == "FooBar"
)

I tried a bit another way:

# added a label 'results' above and then creating a new query
q_foobar_fields = session.query(
    func.json_array_elements(subq_result_elems.c.results.op("->")("Field"))
).filter(
    subq_result_elems.c.results.op("->>")("Name") == "FooBar",
)

print(str(q_foobar_fields.statement.compile(compile_kwargs={"literal_binds": True}, dialect=postgresql.dialect())))

but it creates this SQL:

SELECT json_array_elements(subq_result_elems.results -> 'Field') AS json_array_elements_1
FROM (SELECT check_inside.response -> 'Results' AS results
      FROM "check" AS check_inside,
           "check" AS check_
      WHERE check_inside.id = check_.id) AS subq_result_elems
WHERE (subq_result_elems.results ->> 'Name') = 'FooBar';

and here ‘FROM’ is different from what I need (and it creates multiple rows for each check item)

How can I pass an aliased subquery and refer it in the ‘select’ part?

Thanks in advance!

Versions

  • SQLAlchemy: 1.3.18
  • Database: Postgres

Have a nice day!

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:8 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
zzzeekcommented, Jan 15, 2021

the main thing you’re doing that’s not directly supported is a function with a query inside of it, which then goes into the FROM clause, which is very much a postgresql thing. you can probably find a recipe that can help if you take a look at #3566 which has a whole set of POCs for how to get these unusual PG syntaxes to work. This is stuff that we’d like to add as a feature but it never has gotten priority.

take a look through those and if you can’t get it working, I will add your example above to the list on that issue. basically when the feature gets added, all those comments will serve as test cases.

0reactions
mahenzoncommented, Jan 18, 2021

oh, that’s great! yeah, now it’s correct thank you very much!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Subqueries' aliases same as main queries' aliases
It's OK for nested subqueries to use the same aliases as used in the parent query, although it might be a bit confusing...
Read more >
SQL Creating an Alias Column For a Nested Select?
Say I have a Person table and a Courses table. In the Person table I have the column PersonName . In the Courses...
Read more >
Subquery Examples - SAS Help Center
This example queries tables WORLDTEMPS and WORLDCITYCOORDS by specifying a subquery in the FROM clause. This example uses the subquery to ...
Read more >
How to Use Aliases in SQL Queries - LearnSQL.com
There are several ways to use aliases in your SQL queries. This article shows you how, using simple explanations and helpful examples.
Read more >
SQL Nested subquery - w3resource
Nested subqueries. A subquery can be nested inside other subqueries. SQL has an ability to nest queries within one another. A subquery is...
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