📜  SQLAlchemy核心-使用集合操作

📅  最后修改于: 2020-11-27 07:41:32             🧑  作者: Mango


在上一章中,我们了解了各种函数,例如max(),min(),count()等,在这里,我们将了解集合操作及其用法。

标准SQL及其大多数方言支持诸如UNION和INTERSECT之类的集合操作。 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语句未返回的行。 exclude_()函数使用EXCEPT子句生成SELECT表达式。

在以下示例中,exception_()函数仅返回地址表中那些在email_add字段中具有“ gmail.com”的记录,但不包括那些在postal_add字段中具有“ Pune”的记录。

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 ?

两个绑定参数’%gmail.com’和’%Pune’从地址表中的原始数据生成一行,如下所示-

[(1, 1, 'Shivajinagar Pune', 'ravi@gmail.com')]