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]')]