쿼리문에 join이 필요한 경우

2024년 2월 19일 월요일

Today I Learned

날짜

2024년 2월 19일 월요일

내용

SQL 쿼리문에서 Join

그동안 쿼라를 이용해 관계(relationship)를 맺고 있는 여러 데이터를 가져올때 joinedload를 사용했다. 예를 들어, shop_detail 테이블에 있는 필드 use_ai는 우리 서비스에서 AI 기능을 사용하는 지를 나타낸다. id가 shop_id로 일치하는 Shop을 불러올 때, shop_detail도 같이 가져오기 위해 쿼리문을 다음과 같이 작성할 수 있다.

1
2
stmt = select(models.Shop).options(joinedload(models.Shop.shop_detail).where(models.Shop.id == shop_id)
result = db.execute(stmt).scalar_one_or_none()

이 떄, result는 [models.Shop](http://models.Shop) 형식이겠지만, shop_detail을 참조할 수 있다. print(result.shop_detail.use_review)와 같은 형식으로!

만약 shop을 가져올 때, 관계가 있는 shop_detail의 특정 필드를 조건으로 가져온다면 어떨까? shop 중 관계된 shop_detail의 use_review 가 False인 것만 가져오는 쿼리문을 작성해보자.

1
2
stmt = select(models.Shop).options(joinedload(models.Shop.shop_detail).where(models.Shop.shop_detail.use_review == False)
result = db.execute(stmt).scalar_one_or_none()

이렇게 작성했는데 오류가 발생했다. 쿼리문 자체에서 참조하기 위해선, JOIN하는 과정을 추가해주어야 한다. 따라서 다음과 같이 작성하면 된다.

1
2
stmt = select(models.Shop).join(models.Shop.shop_detail).where(models.Shop.shop_detail.use_review == False).options(joinedload(models.Shop.shop_detail))
result = db.execute(stmt).scalars().all()

쿼리를 실행하고 사용하지 않고, 탐색 중의 조건은 Join이 선행되어야 한다.

회고

건강이 최고다.