📅  最后修改于: 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被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')]