SQLAlchemy Core - 使用集合操作



在上一章中,我們學習了各種函式,例如 max()、min()、count() 等,在這裡,我們將學習集合操作及其用途。

標準 SQL 及其大多數方言都支援 UNION 和 INTERSECT 等集合操作。SQLAlchemy 透過以下函式實現了它們:

union()

在組合兩個或多個 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()

union 結構轉換為以下 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 ?

從我們的 addresses 表中,以下行表示 union 操作:

[
   (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 ?

except_()

SQL 的EXCEPT 子句/運算子用於組合兩個 SELECT 語句,並返回第一個 SELECT 語句中未被第二個 SELECT 語句返回的行。except_() 函式生成一個帶有 EXCEPT 子句的 SELECT 表示式。

在以下示例中,except_() 函式僅返回 addresses 表中在 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 ?

假設 addresses 表包含前面示例中使用的資料,它將顯示以下輸出:

[(2, 1, 'ChurchGate Mumbai', 'kapoor@gmail.com'),
   (3, 3, 'Jubilee Hills Hyderabad', 'komal@gmail.com')]

intersect()

使用 INTERSECT 運算子,SQL 會顯示兩個 SELECT 語句的公共行。intersect() 函式實現了此行為。

在以下示例中,兩個 SELECT 結構是 intersect() 函式的引數。一個返回在 email_add 列中包含“gmail.com”的行,另一個返回在 postal_add 列中包含“Pune”的行。結果將是兩個結果集的公共行。

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”從 addresses 表中的原始資料生成一行,如下所示:

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

© . All rights reserved.