본문 바로가기
DataBase/MS-SQL

[MS-SQL] 서브 쿼리 검색 조건 'WHERE EXISTS' 절의 구조와 활용

by 너울림 2023. 1. 12.

대표 이미지

 

서브 쿼리 검색 조건 '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
반응형

실행 결과


테스트 예제의 실행 결과입니다. 구조와 개념만 이해한다면 쉽게 활용가능한 구문입니다.

실행 결과
실행 결과


참고 링크

 

2022.12.24 - [DataBase/MS-SQL] - [MS-SQL] 다중 레코드 INSERT 하기

 

[MS-SQL] 다중 레코드 INSERT 하기

다중 레코드 INSERT 하기 상황에 맞는 Insert문 구사가 중요하다 포스팅 개요 저는 주로 레코드를 추가할 때 다음 3가지 방식을 가장 많이 사용합니다 단일 레코드 추가 방식 예) INSERT INTO Table_name (

ullim.net

https://learn.microsoft.com/ko-kr/sql/t-sql/language-elements/exists-transact-sql?f1url=%3FappId%3DDev15IDEF1%26l%3DKO-KR%26k%3Dk(EXISTS_TSQL)%3Bk(sql13.swb.tsqlresults.f1)%3Bk(sql13.swb.tsqlquery.f1)%3Bk(MiscellaneousFilesProject)%3Bk(DevLang-TSQL)%26rd%3Dtrue&view=sql-server-ver16 

 

EXISTS(Transact-SQL) - SQL Server

EXISTS(Transact-SQL)

learn.microsoft.com

댓글