(SQL 첫걸음) 데이터 베이스 #6

jjinny_0609·2023년 3월 16일
0

데이터베이스

목록 보기
16/17

상관서브쿼리

EXISTS

Syntax EXISTS
EXISTS (SELECT 명령)

select 했을때 그 테이블에 데이터가 있는지 없는지를 판별할 때 사용한다.
서브쿼리는 적어도 하나의 행을 반환해야 EXISTS가 참을 반환합니다. 서브쿼리가 행을 반환하지 않으면 EXISTS는 거짓을 반환합니다.
추가하려는 데이터가 테이블에 있는지를 판별해서
없으면 insert
있으면 update
[예제 sample551 테이블과 sample552 테이블]
[sample551]

[sample552]


EXISTS 예제

update sample551 set a = '있음' where exists(select * from sample552 where no2 = no);
select * from sample551;


값이 '있음'으로 갱신되었다.


NOT EXISTS 예제

update sample551 set a = '없음' where not exists(select * from sample552 where no2 = no);
select * from sample551;


값이 '없음'으로 갱신되었다.

상관 서브쿼리

상관 서브쿼리는 외부 쿼리와 내부 서브쿼리 간의 관계를 이용하여 내부 서브쿼리의 결과를 결정하는 방식으로 동작하는 서브쿼리입니다. 상관 서브쿼리는 내부 서브쿼리에서 외부 쿼리의 컬럼을 참조하는데, 이를 이용하여 서브쿼리의 결과를 도출합니다. 상관 서브쿼리는 보통 EXISTS나 IN 연산자와 함께 사용됩니다.

  • 테이블 명 붙이기
    상관 서브쿼리에서는 메인 쿼리와 서브쿼리에서 사용하는 테이블의 열 이름이 같을 경우, 열 이름 앞에 테이블 별칭(table alias)을 사용하여 명확하게 구분해주어야 합니다. 이렇게 하지 않으면 쿼리가 실행되지 않거나 잘못된 결과가 나올 수 있습니다.

예를 들어, 다음과 같은 쿼리가 있다고 가정해봅시다.

SELECT *
FROM orders
WHERE order_date > (
  SELECT order_date
  FROM customers
  WHERE customers.customer_id = orders.customer_id
)

이 경우, 메인 쿼리와 서브쿼리에서 모두 order_date 열을 사용하고 있습니다. 이때 메인 쿼리와 서브쿼리에서 각각 다른 order_date 열을 참조하도록 하기 위해서는 서브쿼리에서 테이블 별칭을사용하여 다음과 같이 수정해주어야 합니다.

SELECT *
FROM orders
WHERE order_date > (
  SELECT c.order_date
  FROM customers c
  WHERE c.customer_id = orders.customer_id
)

이렇게 하면 메인 쿼리에서는 orders 테이블의 order_date 열을, 서브쿼리에서는 customers 테이블의 order_date 열을 참조하게 됩니다. 이를 통해 쿼리가 정확히 실행되어 원하는 결과를 얻을 수 있습니다.

IN

Syntax IN
열명 IN(집합)

IN은 여러 개의 값을 비교할 때 사용하는 연산자입니다. IN 연산자는 특정 열이 지정된 값을 포함하는 경우에 해당 레코드를 반환합니다.

예를 들어, 다음과 같은 쿼리가 있다고 가정해봅시다.

SELECT *
FROM customers
WHERE country IN ('USA', 'Canada', 'Mexico')

이 쿼리는 customers 테이블에서 country 열이 'USA', 'Canada', 또는 'Mexico'인 레코드를 모두 반환합니다. IN 연산자는 여러 개의 값을 비교할 때 유용하며, 이를 통해 복잡한 조건을 간단하게 표현할 수 있습니다.

IN 연산자는 다른 SQL 연산자와 함께 사용될 수도 있습니다. 예를 들어, NOT IN 연산자를 사용하면 특정 값을 포함하지 않는 레코드를 반환할 수 있습니다.

SELECT *
FROM customers
WHERE country NOT IN ('USA', 'Canada', 'Mexico')

이 쿼리는 customers 테이블에서 country 열이 'USA', 'Canada', 또는 'Mexico'이 아닌 레코드를 반환합니다. 이를 통해 필요한 값을 포함하지 않는 레코드를 쉽게 필터링할 수 있습니다.

[예제_IN을 사용해 조건식 기술]

-- SAMPLE551 테이블에서 NO열의 값이 3또는 5인것만 조회
SELECT * FROM sample551 WHERE no = 3 or no = 5;	-- or 키워드
SELECT * FROM sample551 WHERE no IN(3, 5); 		-- in 키워드


[복습]

  1. 스칼라
    SELECT (SELECT * FROM 테이블명)
    FROM 테이블명

  2. 서브쿼리
    SELECT
    FROM 테이블명
    WHERE 열명 = (SELECT FROM 테이블명)
    2-1. 단일행 서브쿼리[ = ] : 소괄호 안의 select의 결과가 하나인 경우
    2-2. 다중행 서브쿼리[IN, ANY, ALL] : 소괄호 안의 select의 결과가 두개(줄) 이상인 경우

  3. 인라인뷰(as키워드를 이용하여 가상의 테이블명 반드시!! 꼭!! 선언해야 함.)
    SELECT
    FROM (SELECT FROM 테이블명) AS 가상테이블명

IN, ANY, ALL에 대한 설명

IN : 특정 열이 지정된 값들 중 하나와 일치하는 레코드를 반환합니다.

SELECT *
FROM customers
WHERE country IN ('USA', 'Canada', 'Mexico')
이 쿼리는 customers 테이블에서 country 열이 'USA', 'Canada', 또는 'Mexico'인 레코드를 모두 반환합니다.

ANY : 서브쿼리에서 반환된 값들 중 하나와 일치하는 레코드를 반환합니다.

SELECT *
FROM orders
WHERE total_amount > ANY (
    SELECT total_amount
    FROM orders
    WHERE order_date = '2022-01-01'
)
이 쿼리는 orders 테이블에서 order_date가 2022년 1월 1일인 주문 중에 가장 작은 total_amount보다 큰 
total_amount를 가진 레코드를 반환합니다.

ALL : 서브쿼리에서 반환된 값들과 모두 일치하는 레코드를 반환합니다.

ALL 예제1)
SELECT *
FROM orders
WHERE total_amount > ALL (
    SELECT total_amount
    FROM orders
    WHERE order_date = '2022-01-01'
)
orders 테이블에서 order_date가 2022년 1월 1일인 주문 중에서 가장 큰 total_amount보다 큰 
total_amount를 가진 레코드를 반환합니다.
ALL 예제2)
select *
	from sample551	-- 서브결과 : 3, 5
	where no >= all (select no2 from sample552);


IN과 NULL

IN 연산자는 특정 열이 지정된 값들 중 하나와 일치하는 레코드를 반환합니다. 그러나 IN 연산자를 사용할 때 주의해야 할 점 중 하나는, 지정된 값들 중 하나가 NULL인 경우에 대한 처리입니다.

NULL은 값이 없음을 나타내는 특수한 값으로, 다른 값들과 다르게 비교 연산을 할 때 예상치 못한 결과를 내는 경우가 있습니다. 따라서 IN 연산자를 사용할 때는 NULL 값에 대한 처리를 명시적으로 지정해주어야 합니다.

예를 들어, 다음과 같은 쿼리가 있다고 가정해봅시다.

SELECT *
FROM customers
WHERE country IN ('USA', 'Canada', NULL)

이 쿼리에서 IN 연산자로 지정된 값들 중 하나가 NULL인 경우, 해당 레코드를 반환하지 않습니다. 따라서 이 쿼리는 customers 테이블에서 country 열이 'USA' 또는 'Canada'인 레코드만을 반환하며, country 열이 NULL인 레코드는 반환하지 않습니다.

NULL 값에 대한 처리를 명시적으로 지정하려면, IS NULL 또는 IS NOT NULL 연산자를 사용해야 합니다. 예를 들어, 다음과 같은 쿼리를 사용하여 NULL 값을 포함하는 레코드를 반환할 수 있습니다.

SELECT *
FROM customers
WHERE country IN ('USA', 'Canada')
OR country IS NULL

이 쿼리는 customers 테이블에서 country 열이 'USA', 'Canada', 또는 NULL인 레코드를 모두 반환합니다. 이를 통해 NULL 값에 대한 처리를 명시적으로 지정할 수 있습니다.

profile
뉴비 개발자 입니다. velog 주소 : https://velog.io/@jjinny_0609 Github 주소 :

0개의 댓글