공부/MSSQL

MSSQL Scalar subquery

da_won_2023 2023. 8. 17. 23:49
SMALL

Subquery

- SQL문 안에 있는 SQL문을 의미한다.

● 소괄호로 감싸 사용한다.

● 서브쿼리 안에서는 ORDER BY를 사용하지 못한다.

Scalar subquery

- 한 레코드에 한 값만을 반환하는 서브쿼리를 의미한다.

● 조인 키 값의 종류가 한정적이고 동일한 것이 많을 때 주로 사용한다.

● 장점으로는 캐시효과. 단점으로는 반복수행이다.

● 캐시효과로 인해 데이터가 적을 때 유리하지만 데이터가 많을 때는 반복수행으로 오히려 성능이 더 떨어진다.

 

Hackerrank의 New Companies를 예제로 하였다.

예제 데이터는 밑에 준비해두었다.

 

 

DECLARE @COMPANY TABLE
(
        COMPANY_CODE NVARCHAR(30)
        ,	FOUNDER NVARCHAR(100)
)

DECLARE @LEAD_MANAGER TABLE (
        LEAD_MANAGER_CODE NVARCHAR(30)
        ,	COMPANY_CODE NVARCHAR(30)
)

DECLARE @SENIOR_MANAGER TABLE (
        SENIOR_MANAGER_CODE NVARCHAR(30)
        ,	LEAD_MANAGER_CODE NVARCHAR(30)
        ,	COMPANY_CODE NVARCHAR(30)
)

DECLARE @MANAGER TABLE (
        MANAGER_CODE NVARCHAR(30)
        ,	SENIOR_MANAGER_CODE NVARCHAR(30)
        ,	LEAD_MANAGER_CODE NVARCHAR(30)
        ,	COMPANY_CODE NVARCHAR(30)
)

DECLARE @EMPLOYEE TABLE (
        EMPLOYEE_CODE NVARCHAR(30)
        ,	MANAGER_CODE NVARCHAR(30)
        ,	SENIOR_MANAGER_CODE NVARCHAR(30)
        ,	LEAD_MANAGER_CODE NVARCHAR(30)
        ,	COMPANY_CODE NVARCHAR(30)
)

INSERT INTO @COMPANY VALUES('C1','Monika')
INSERT INTO @COMPANY VALUES('C2','Samantha')


INSERT INTO @LEAD_MANAGER VALUES('LM1','C1')
INSERT INTO @LEAD_MANAGER VALUES('LM2','C2')

INSERT INTO @SENIOR_MANAGER VALUES('SM1','LM1','C1')
INSERT INTO @SENIOR_MANAGER VALUES('SM2','LM1','C1')
INSERT INTO @SENIOR_MANAGER VALUES('SM3','LM2','C2')

INSERT INTO @MANAGER VALUES ('M1','SM1','LM1','C1')
INSERT INTO @MANAGER VALUES ('M2','SM2','LM2','C2')
INSERT INTO @MANAGER VALUES ('M3','SM3','LM2','C2')

INSERT INTO @EMPLOYEE VALUES ('E1','M1','SM1','LM1','C1')
INSERT INTO @EMPLOYEE VALUES ('E2','M1','SM1','LM1','C1')
INSERT INTO @EMPLOYEE VALUES ('E3','M2','SM2','LM2','C2')
INSERT INTO @EMPLOYEE VALUES ('E4','M3','SM3','LM2','C2')

 

 

< 조건> 에는

- 아래의 테이블 스키마를 참조하여

COMPANY_CODE(회사코드)

FOUNDER(설립자)

TOTAL NUMBER OF LEAD_MANAGERS(총 리드 매니저 수)

TOTAL NUMBER OF SENIOR_MANAGERS(총 시니어 매니저 수)

TOTAL NUMBER OF MANAGERS(총 매니저 수)

TOTAL NUMBER OF EMPLOYEES(총 직원 수)

를 출력하기 위한 SQL문을 작성하세요.

- COMPANY_CODE 오름차순으로 정렬하세요.

< 메모 >에는

- 테이블에는 중복된 레코드가 포함될 수 있습니다.

- COMPANY_CODE가 문자열이므로 정렬은 숫자일 수 없습니다.

예를 들어, COMPANY_CODE가 C1,C2,C10이면 오름차순으로 정렬했을 때 COMPANY_CODE는 C1,C10,C2가 됩니다.

이러한 전제가 있을 때 고려해야 할 사항은

- 각 매니저와 직원을 COUNT해야한다.

- 중복된 레코드에 대하여 중복제거를 해야 한다.

나는 Scalar subquery를 이용해 아래와 같이 문제를 풀었다.

 

 

SELECT	
        A.COMPANY_CODE
        ,	A.FOUNDER
        ,	(SELECT COUNT(*) FROM ( SELECT DISTINCT * FROM @LEAD_MANAGER WHERE COMPANY_CODE = A.COMPANY_CODE) A)
        ,	(SELECT COUNT(*) FROM ( SELECT DISTINCT * FROM @SENIOR_MANAGER WHERE COMPANY_CODE = A.COMPANY_CODE) A)
        ,	(SELECT COUNT(*) FROM ( SELECT DISTINCT * FROM @MANAGER WHERE COMPANY_CODE = A.COMPANY_CODE) A)
        ,	(SELECT COUNT(*) FROM ( SELECT DISTINCT * FROM @EMPLOYEE WHERE COMPANY_CODE = A.COMPANY_CODE) A)
FROM @COMPANY A
ORDER BY A.COMPANY_CODE

 

하지만 이 외에도 풀 수 있는 방법은 많다.

 

DISTINCT 대신 GROUP BY를 활용할 수도 있고, Scalar subquery 대신 JOIN을 활용할 수 있다.

LIST