서브 쿼리 검색 조건 'WHERE EXISTS' 절의 구조와 활용
포스팅 개요
'WHERE EXISTS' 절은 서브 쿼리가 행을 반환하는지 여부를 기준으로 결과를 조회하는 논리 연산자입니다. 이 구문은 MS-SQL뿐 아니라 MySQL, Postgre 같은 다른 관계형 데이터 베이스에도 동일한 방식으로 작동합니다. 그럼 오늘 포스팅에서는 'WHERE EXISTS' 절의 구조와 사용법 그리고 예제 쿼리로 활용까지 해보도록 하겠습니다.
- 서브쿼리가 결과가 반환되는 데이터 조회 방법
-- 서브쿼리가 반환되는 조건의 데이터 조회
SELECT column1, column2, ...
FROM Test_table
WHERE EXISTS (subquery)
- 서브쿼리가 결과가 반환되지 않는 데이터 조회 방법
-- 서브쿼리가 반환되지 않는 조건의 데이터 조회
SELECT column1, column2, ...
FROM Test_table
WHERE NOT EXISTS (subquery)
예제 쿼리
먼저 위와 같은 2개의 예제 테이블을 생성해 보겠습니다. ※ 테스트 테이블 및 데이터 생성 쿼리도 예제에 포함시켜 두겠습니다.
물품 입고 내역 테이블과 불량 내역 테이블 2개를 생성하였으면 'WHERE EXISTS' 절을 활용하여 2022년 12월에 발생한 불량 물품의 입고내역을 검색하는 쿼리문을 작성해 보겠습니다.
-- 불량 재고가 발생한 년월의 입고 내역 조회
SELECT * FROM In_Table
WHERE EXISTS (
SELECT 1 FROM Defective_Stock
WHERE Df_Date = '2022-12' AND Df_Stock = Stock AND Df_Date = LEFT(In_Date,7)
)
예제의 서브 쿼리는 반환 결과를 위해 'Select 1'을 적어두었지만 아무 필드나 적으셔도 상관없습니다. 중요한 건 조건에 맞춰 반환값이 있냐 없느냐 차이를 두고 필터링이 되기 때문입니다. 그럼 'WHERE NOT EXISTS' 절을 활용하여 반대의 경우도 조회하도록 하겠습니다. 예제와 같은 상황이라면 불량 물품을 제외한 정상 입고 내역을 검색하는 쿼리문입니다.
-- 불량품을 제외한 입고 내역 조회
SELECT * FROM In_Table
WHERE NOT EXISTS (
SELECT 0 FROM Defective_Stock
WHERE Df_Date = '2022-12' AND Df_Stock = Stock AND Df_Date = LEFT(In_Date,7)
)
비슷한 구문으로 IN이나 ANY 같은 구문이 존재하지만 단순 비교 구문을 넘어서 서브 쿼리 전체를 반환하는 경우에는 'WHERE EXISTS' 절을 사용하는 것이 더 유리합니다. 이어서 테스트 테이블 및 데이터 생성 쿼리도 추가로 남겨두겠습니다.
-- 입고 테이블을 중복 생성을 막기 위한 테이블 유무 검사
IF OBJECT_ID ('[dbo].[In_Table]') IS NOT NULL DROP TABLE [dbo].[In_Table]
-- 입고 테이블 생성
CREATE TABLE In_Table(
[ID] [INT] IDENTITY (1, 1) NOT NULL, --Key = 증가
[In_Date] [VARCHAR](10) NULL, -- 입고일자
[Employee] [VARCHAR](50) NULL, -- 사원
[Stock] [VARCHAR](50) NULL, -- 입고품
[Qty] [INT] NULL -- 수량
PRIMARY KEY ([ID])
)
-- 입고 테이블에 INSERT
INSERT INTO In_Table([In_Date],[Employee],[Stock],[Qty]) VALUES
('2022-12-01', '너울림', '사과', 100),
('2022-12-01', '너울림', '배', 120),
('2022-12-02', 'ullim', '바나나', 50),
('2022-12-07', '너울림', '바나나', 70),
('2022-12-07', 'ullim', '사과', 230),
('2022-12-08', 'ullim', '사과', 30),
('2022-12-09', '너울림', '귤', 150),
('2022-12-15', '너울림', '귤', 150),
('2022-12-15', 'ullim', '바나나', 150)
-- 입고 테이블 조회
SELECT * FROM In_Table
-- 불량 테이블을 중복 생성을 막기 위한 테이블 유무 검사
IF OBJECT_ID ('[dbo].[Defective_Stock]') IS NOT NULL DROP TABLE [dbo].[Defective_Stock]
-- 불량 테이블 생성
CREATE TABLE Defective_Stock(
[Df_ID] [INT] IDENTITY (1, 1) NOT NULL, --Key = 증가
[Df_Date] [VARCHAR](7) NULL, -- 불량발생 월
[Df_Stock] [VARCHAR](50) NULL, -- 불량품
[Df_Qty] [INT] NULL -- 수량
PRIMARY KEY ([Df_ID])
)
-- 불량 테이블에 INSERT
INSERT INTO Defective_Stock([Df_Date],[Df_Stock],[Df_Qty]) VALUES
('2022-11', '사과', 100),
('2022-11', '배', 100),
('2022-12', '바나나', 50),
('2022-12', '배', 70),
('2023-01', '사과', 230),
('2022-01', '바나나', 30)
-- 불량 테이블 조회
SELECT * FROM Defective_Stock
실행 결과
테스트 예제의 실행 결과입니다. 구조와 개념만 이해한다면 쉽게 활용가능한 구문입니다.
참고 링크
'DataBase > MS-SQL' 카테고리의 다른 글
[MS-SQL] Microsoft SQL Server Express 모든 버전(~2022) 다운로드 설치 링크 (0) | 2024.12.31 |
---|---|
[MS-SQL] RAND 함수 활용하여 랜덤 일자(날짜), 시간 생성하기 (0) | 2023.02.08 |
[MS-SQL] 문자열에서 숫자만 추출하기 (스칼라 반환 함수) (0) | 2023.01.13 |
[MS-SQL] 특정 컬럼에서 소수점이 존재하는 레코드 조회하기 (0) | 2023.01.05 |
[MS-SQL] Create Table 생략하고 임시 테이블 생성 (Select Into) (0) | 2023.01.04 |
[MS-SQL] 그룹별 ROW(행) 문자열 결과 합치기 (STUFF, FOR XML PATH 활용) (0) | 2023.01.03 |
[MS-SQL] 중복 테이블 삭제 후에 다시 테이블 생성(CREATE)하기 (0) | 2023.01.02 |
[MS-SQL] 다중 레코드 INSERT 하기 (0) | 2022.12.24 |
댓글