본문 바로가기
Backend/TypeORM

스칼라 서브쿼리

by 찬찬2 2023. 4. 7.

 

테이블은 이전 게시글에서 사용해했던 pokemon 과 ability 이다.

 

PRIMARY_ABILITY, SUB_ABILITY 값으로 ability 테이블 NAME 컬럼에서 이름을 가져오고 싶다.

 

우선 쿼리를 먼저 그려보면,

 

SELECT
	"NAME",
	"NUMBER",
 	(SELECT "NAME" FROM ability WHERE ability."ID" = pokemon."PRIMARY_ABILITY" ) AS p_ability,
	(SELECT "NAME" FROM ability WHERE ability."ID" = pokemon."SUB_ABILITY" ) AS s_ability
FROM pokemon;

 

이러하다. 정말 간단하지 않은가.

 

결과는,

 

 

원하는 형태로 잘나왔다. 그렇다면 스칼라 서브쿼리를 Typeorm은 어떻게 구현할까?? (공식문서 링크)

"You can easily create subqueries. Subqueries are supported in FROM, WHERE and JOIN expressions." 라고 써있다. 그리고 조금 더 아래 "You can use subselects in SELECT statements as well" 라고 추가로 써있다.

 

서브쿼리를 사용하기 위해서는 반드시 createQueryBuilder 를 통해서만 작성할 수 있고, FROM, WHERE, JOIN, SELET 절 모든 곳에서 지원된다고 한다.(공식문서 예제) 그 중 SELECT 절에서 서브 쿼리를 작성해보자.

 

정답코드 부터 보자면,

 

const query = await this.dataSource
    .createQueryBuilder()
    .select('pokemon.name', 'name')
    .addSelect('pokemon.number', 'number')
    .addSelect('pokemon.primaryAbility', 'p_ability')
    .addSelect('pokemon.subAbility', 's_ability')
    .addSelect((subQuery) => {
        return subQuery
            .select('ability.name', 'p_ability_nm')
            .from(Ability, 'ability')
            .where('ability.id = pokemon.primaryAbility')
    })
    .addSelect((subQuery) => {
        return subQuery
            .select('ability.name', 's_ability_nm')
            .from(Ability, 'ability')
            .where('ability.id = pokemon.subAbility')
    })
    .from(Pokemon, 'pokemon')
    .getRawMany();

 

addSelect 매서드를 사용하는 것이다. addSelect는 단순히 컬럼명을 넣고 alias를 지정할때 사용하기도 하지만 콜백함수로 인자를 넣으면 SELECT 절에서 다시 SELECT 절이 탄생해 스칼라 서브 쿼리처럼 되는 것이다.

 

결과는,

 

댓글