В последней главе мы узнали о различных функциях, таких как 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', '[email protected]'), (2, 1, 'ChurchGate Mumbai', '[email protected]'), (3, 3, 'Jubilee Hills Hyderabad', '[email protected]'), (4, 5, 'MG Road Bangaluru', '[email protected]') ]
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', '[email protected]'), (3, 3, 'Jubilee Hills Hyderabad', '[email protected]')]
пересекаются ()
Используя оператор 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 ?
Два связанных параметра «% gmail.com» и «% Pune» генерируют одну строку из исходных данных в таблице адресов, как показано ниже —