Метод subquery класса Select
Метод subquery класса Select
превращает текущий SELECT-запрос в подзапрос.
Подзапрос можно использовать в других запросах,
например, в конструкциях FROM, JOIN или WHERE.
Метод необязательно принимает имя подзапроса
в качестве параметра. Если имя не указано,
SQLAlchemy генерирует его автоматически.
Синтаксис
select_stmt.subquery([name])
Пример
Давайте создадим простой подзапрос из SELECT-запроса и выведем его:
from sqlalchemy import select, table, column
articles = table(
'articles',
column('id'),
column('title'),
)
stmt = select(articles.c.id, articles.c.title)
subq = stmt.subquery()
print(subq)
Результат выполнения кода:
"SELECT anon_1.id, anon_1.title FROM (SELECT articles.id AS id, articles.title AS title FROM articles) AS anon_1"
Пример
Давайте передадим подзапросу явное имя
параметром name:
from sqlalchemy import select, table, column
articles = table(
'articles',
column('id'),
column('title'),
)
stmt = select(articles.c.id, articles.c.title)
subq = stmt.subquery('article_subq')
print(subq)
Результат выполнения кода:
"SELECT article_subq.id, article_subq.title FROM (SELECT articles.id AS id, articles.title AS title FROM articles) AS article_subq"
Пример
Давайте используем подзапрос в конструкции
JOIN вместе с основной таблицей:
from sqlalchemy import select, table, column
articles = table(
'articles',
column('id'),
column('title'),
column('status'),
)
subq = (
select(articles.c.id, articles.c.title)
.where(articles.c.status == 'published')
.subquery('published_articles')
)
stmt = select(articles.c.id, subq.c.title).join(
subq, articles.c.id == subq.c.id
)
print(stmt)
Итоговый SQL запрос:
SELECT articles.id, published_articles.title
FROM articles
JOIN (
SELECT articles.id AS id, articles.title AS title
FROM articles
WHERE articles.status = :status_1
) AS published_articles ON articles.id = published_articles.id
Пример
Давайте используем подзапрос в условии
WHERE через оператор in_:
from sqlalchemy import select, table, column
articles = table(
'articles',
column('id'),
column('title'),
column('status'),
)
subq = (
select(articles.c.id)
.where(articles.c.status == 'published')
.subquery()
)
stmt = select(articles.c.id, articles.c.title).where(
articles.c.id.in_(select(subq.c.id))
)
print(stmt)
Итоговый SQL запрос:
SELECT articles.id, articles.title
FROM articles
WHERE articles.id IN (
SELECT anon_1.id FROM (
SELECT articles.id AS id
FROM articles
WHERE articles.status = :status_1
) AS anon_1
)