SQLAlchemyCore-セット操作の使用
前の章では、max()、min()、count()などのさまざまな関数について学習しました。ここでは、集合演算とその使用法について学習します。
UNIONやINTERSECTなどのセット操作は、標準SQLとその方言のほとんどでサポートされています。SQLAlchemyは、次の関数を使用してそれらを実装します-
連合()
UNIONは、2つ以上のSELECTステートメントの結果を結合するときに、結果セットから重複を排除します。列の数とデータ型は、両方のテーブルで同じである必要があります。
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', '[email protected]'),
(2, 1, 'ChurchGate Mumbai', '[email protected]'),
(3, 3, 'Jubilee Hills Hyderabad', '[email protected]'),
(4, 5, 'MG Road Bangaluru', '[email protected]')
]
union_all()
UNION ALL操作では、重複を削除したり、結果セット内のデータを並べ替えたりすることはできません。たとえば、上記のクエリでは、効果を確認するためにUNIONがUNIONALLに置き換えられています。
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句/演算子は、2つのSELECTステートメントを組み合わせて、最初のSELECTステートメントから2番目のSELECTステートメントでは返されない行を返すために使用されます。exception_()関数は、EXCEPT句を使用してSELECT式を生成します。
次の例では、except_()関数は、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', '[email protected]'),
(3, 3, 'Jubilee Hills Hyderabad', '[email protected]')]
交差()
SQLは、INTERSECT演算子を使用して、両方のSELECTステートメントからの共通行を表示します。交差()関数はこの動作を実装します。
次の例では、2つのSELECT構造がintersect()関数のパラメーターです。1つはemail_add列の一部として「gmail.com」を含む行を返し、もう1つは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 ?
2つのバインドされたパラメータ '%gmail.com'と '%Pune'は、以下に示すように、アドレステーブルの元のデータから単一の行を生成します-
[(1, 1, 'Shivajinagar Pune', '[email protected]')]