SQLAlchemy Core-집합 연산 사용

지난 장에서 우리는 max (), min (), count () 등과 같은 다양한 함수에 대해 배웠습니다. 여기서 우리는 집합 연산과 그 용도에 대해 배울 것입니다.

UNION 및 INTERSECT와 같은 집합 연산은 표준 SQL 및 대부분의 언어에서 지원됩니다. 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', '[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은 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 문에서 행을 반환하는 데 사용됩니다. except_ () 함수는 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]')]

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'은 아래와 같이 주소 테이블의 원본 데이터에서 단일 행을 생성합니다.

[(1, 1, 'Shivajinagar Pune', '[email protected]')]