Функция except_all
Функция except_all объединяет два
SELECT-запроса оператором EXCEPT ALL.
Первый параметр - это запрос, из которого
исключаются строки, второй - запрос, строки
которого вычитаются. В отличие от except_,
оператор EXCEPT ALL не удаляет дубликаты
и сохраняет их в результирующем наборе.
Функция принимает два позиционных аргумента - исходный запрос и вычитаемый запрос. Оба запроса должны иметь одинаковое количество колонок с совместимыми типами данных.
Синтаксис
except_all(select1, select2)
Пример
Давайте создадим две выборки из таблицы
articles и объединим их оператором
EXCEPT ALL:
from sqlalchemy import create_engine, select, except_all
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article', text='text 1', status='active', num=1),
Article(title='article', text='text 2', status='active', num=2),
Article(title='user', text='text 3', status='draft', num=3),
])
session.commit()
select1 = select(Article.title)
select2 = select(Article.title).where(Article.status == 'draft')
stmt = except_all(select1, select2)
res = session.execute(stmt).scalars().all()
print(res)
Результат выполнения кода:
['article', 'article']
Пример
Давайте сравним поведение except_all
и except_ на одинаковых данных:
from sqlalchemy import create_engine, select, except_, except_all
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article', text='text 1', status='active', num=1),
Article(title='article', text='text 2', status='active', num=2),
Article(title='user', text='text 3', status='draft', num=3),
])
session.commit()
select1 = select(Article.title)
select2 = select(Article.title).where(Article.status == 'draft')
res_all = session.execute(except_all(select1, select2)).scalars().all()
res_distinct = session.execute(except_(select1, select2)).scalars().all()
print('EXCEPT ALL:', res_all)
print('EXCEPT:', res_distinct)
Результат выполнения кода:
"EXCEPT ALL: ['article', 'article']"
"EXCEPT: ['article']"
Пример
Давайте посмотрим итоговый SQL-запрос,
который генерирует функция except_all:
from sqlalchemy import create_engine, select, except_all
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
select1 = select(Article.title)
select2 = select(Article.title).where(Article.status == 'draft')
stmt = except_all(select1, select2)
print(stmt)
Итоговый SQL запрос:
SELECT articles.title
FROM articles
EXCEPT ALL
SELECT articles.title
FROM articles
WHERE articles.status = :status_1
Смотрите также
-
функцию
except_,
которая исключает строки без сохранения дубликатов -
функцию
union_all,
которая объединяет запросы с сохранением дубликатов -
функцию
intersect_all,
которая возвращает общие строки двух запросов -
функцию
select,
которая создает SELECT-запрос