SQLAlchemy Core - Usando operações de conjunto
No último capítulo, aprendemos sobre várias funções, como max (), min (), count (), etc., aqui aprenderemos sobre as operações de conjunto e seus usos.
Operações de conjunto como UNION e INTERSECT são suportadas pelo SQL padrão e a maior parte de seu dialeto. SQLAlchemy os implementa com a ajuda das seguintes funções -
União()
Ao combinar os resultados de duas ou mais instruções SELECT, UNION elimina duplicatas do conjunto de resultados. O número de colunas e o tipo de dados devem ser iguais em ambas as tabelas.
A função union () retorna um objeto CompoundSelect de várias tabelas. O exemplo a seguir demonstra seu uso -
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()
A construção de união se traduz na seguinte expressão 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 ?
De nossa tabela de endereços, as linhas a seguir representam a operação de união -
[
(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 ()
A operação UNION ALL não pode remover as duplicatas e não pode classificar os dados no conjunto de resultados. Por exemplo, na consulta acima, UNION é substituído por UNION ALL para ver o efeito.
u = union_all(addresses.select().where(addresses.c.email_add.like('%@gmail.com')), addresses.select().where(addresses.c.email_add.like('%@yahoo.com')))
A expressão SQL correspondente é a seguinte -
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 ?
exceto_()
O SQL EXCEPTcláusula / operador é usado para combinar duas instruções SELECT e retornar linhas da primeira instrução SELECT que não são retornadas pela segunda instrução SELECT. A função except_ () gera uma expressão SELECT com a cláusula EXCEPT.
No exemplo a seguir, a função except_ () retorna apenas os registros da tabela de endereços que têm 'gmail.com' no campo email_add, mas exclui aqueles que têm 'Pune' como parte do campo postal_add.
u = except_(addresses.select().where(addresses.c.email_add.like('%@gmail.com')), addresses.select().where(addresses.c.postal_add.like('%Pune')))
O resultado do código acima é a seguinte expressão 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 ?
Supondo que a tabela de endereços contenha dados usados nos exemplos anteriores, ela exibirá a seguinte saída -
[(2, 1, 'ChurchGate Mumbai', '[email protected]'),
(3, 3, 'Jubilee Hills Hyderabad', '[email protected]')]
intersectar ()
Usando o operador INTERSECT, o SQL exibe linhas comuns de ambas as instruções SELECT. A função intersect () implementa esse comportamento.
Nos exemplos a seguir, duas construções SELECT são parâmetros para a função intersect (). Um retorna linhas contendo 'gmail.com' como parte da coluna email_add e outro retorna linhas contendo 'Pune' como parte da coluna postal_add. O resultado será linhas comuns de ambos os conjuntos de resultados.
u = intersect(addresses.select().where(addresses.c.email_add.like('%@gmail.com')), addresses.select().where(addresses.c.postal_add.like('%Pune')))
Na verdade, isso é equivalente à seguinte instrução 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 ?
Os dois parâmetros associados '% gmail.com' e '% Pune' geram uma única linha a partir dos dados originais na tabela de endereços, conforme mostrado abaixo -
[(1, 1, 'Shivajinagar Pune', '[email protected]')]