В последней главе мы узнали о различных функциях, таких как max (), min (), count () и т. Д., Здесь мы узнаем об операциях над множествами и их использовании.
Операции над множествами, такие как UNION и INTERSECT, поддерживаются стандартным SQL и большей частью его диалекта. SQLAlchemy реализует их с помощью следующих функций —
союз ()
Объединяя результаты двух или более операторов SELECT, UNION удаляет дубликаты из набора результатов. Количество столбцов и тип данных должны быть одинаковыми в обеих таблицах.
Функция union () возвращает объект CompoundSelect из нескольких таблиц. Следующий пример демонстрирует его использование —
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, union
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()
conn = engine.connect()
addresses = Table(
'addresses', meta,
Column('id', Integer, primary_key = True),
Column('st_id', Integer),
Column('postal_add', String),
Column('email_add', String)
)
u = union(addresses.select().where(addresses.c.email_add.like('%@gmail.com addresses.select().where(addresses.c.email_add.like('%@yahoo.com'))))
result = conn.execute(u)
result.fetchall()
Конструкция объединения переводится в следующее выражение SQL —
SELECT addresses.id, addresses.st_id, addresses.postal_add, addresses.email_add FROM addresses WHERE addresses.email_add LIKE ? UNION SELECT addresses.id, addresses.st_id, addresses.postal_add, addresses.email_add FROM addresses WHERE addresses.email_add LIKE ?
Из нашей таблицы адресов следующие строки представляют операцию объединения —
[ (1, 1, 'Shivajinagar Pune', 'ravi@gmail.com'), (2, 1, 'ChurchGate Mumbai', 'kapoor@gmail.com'), (3, 3, 'Jubilee Hills Hyderabad', 'komal@gmail.com'), (4, 5, 'MG Road Bangaluru', 'as@yahoo.com') ]
union_all ()
Операция UNION ALL не может удалить дубликаты и не может отсортировать данные в наборе результатов. Например, в приведенном выше запросе UNION заменяется на UNION ALL, чтобы увидеть эффект.
u = union_all(addresses.select().where(addresses.c.email_add.like('%@gmail.com')), addresses.select().where(addresses.c.email_add.like('%@yahoo.com')))
Соответствующее выражение SQL выглядит следующим образом:
SELECT addresses.id, addresses.st_id, addresses.postal_add, addresses.email_add FROM addresses WHERE addresses.email_add LIKE ? UNION ALL SELECT addresses.id, addresses.st_id, addresses.postal_add, addresses.email_add FROM addresses WHERE addresses.email_add LIKE ?
Кроме_()
Предложение / оператор SQL EXCEPT используется для объединения двух операторов SELECT и возврата строк из первого оператора SELECT, которые не возвращаются вторым оператором SELECT. Функция exc_ () генерирует выражение SELECT с предложением EXCEPT.
В следующем примере функция exc_ () возвращает только те записи из таблицы адресов, которые имеют «gmail.com» в поле email_add, но исключают те, которые имеют «Pune» как часть поля postal_add.
u = except_(addresses.select().where(addresses.c.email_add.like('%@gmail.com')), addresses.select().where(addresses.c.postal_add.like('%Pune')))
Результатом приведенного выше кода является следующее выражение SQL —
SELECT addresses.id, addresses.st_id, addresses.postal_add, addresses.email_add FROM addresses WHERE addresses.email_add LIKE ? EXCEPT SELECT addresses.id, addresses.st_id, addresses.postal_add, addresses.email_add FROM addresses WHERE addresses.postal_add LIKE ?
Предполагая, что таблица адресов содержит данные, использованные в предыдущих примерах, она будет отображать следующий вывод:
[(2, 1, 'ChurchGate Mumbai', 'kapoor@gmail.com'), (3, 3, 'Jubilee Hills Hyderabad', 'komal@gmail.com')]
пересекаются ()
Используя оператор INTERSECT, SQL отображает общие строки из обоих операторов SELECT. Функция intersect () реализует это поведение.
В следующих примерах две конструкции SELECT являются параметрами для функции intersect (). Одна возвращает строки, содержащие «gmail.com», как часть столбца email_add, а другая возвращает строки, содержащие «Pune» как часть столбца postal_add. Результатом будут общие строки из обоих наборов результатов.
u = intersect(addresses.select().where(addresses.c.email_add.like('%@gmail.com')), addresses.select().where(addresses.c.postal_add.like('%Pune')))
По сути, это эквивалентно следующему оператору SQL —
SELECT addresses.id, addresses.st_id, addresses.postal_add, addresses.email_add FROM addresses WHERE addresses.email_add LIKE ? INTERSECT SELECT addresses.id, addresses.st_id, addresses.postal_add, addresses.email_add FROM addresses WHERE addresses.postal_add LIKE ?