Becker
Becker 의 TIL
Becker
  • 분류 전체보기 (30)
    • Computer Science (15)
      • Python (7)
      • Java (1)
      • Algorithm (0)
      • Database (3)
      • Network (1)
      • Openstack (2)
      • ETC (1)
    • 자동화 (3)
      • Github Action (1)
      • Airflow (0)
      • Docker (2)
    • 논문 리뷰 (1)
    • 서평 (3)
    • 끄적끄적 (8)
전체 방문자
오늘
어제

인기 글

티스토리

hELLO · Designed By 정상우.
Becker

Becker 의 TIL

SQL syntax의 정리 - SELECT문
Computer Science/Database

SQL syntax의 정리 - SELECT문

2022. 12. 27. 16:29

SQL Syntax 정리 - SELECT 구문

  • 이번 포스팅에서는 DML(Data Manufulation Language) 중 하나인 SELECT 구문의 문법에 대해 알아보겠습니다.
  • SELECT 문의 문법 구조와 제공되는 함수를 이해한다면 데이터베이스에서 필요한 정보를 원하는 형태로 조회할 수 있습니다.
  • 예시의 쿼리는 MYSQL 문법을 기준으로 작성되었습니다.

쿼리의 구조

SELECT 컬럼명 FROM 테이블명 WHERE 조건식 GROUP BY 컬럼명 HAVING 조건식 ORDER BY 컬럼명

 

SELECT 쿼리는 일반적으로 위와 같은 구조로 작성됩니다. 각 명령어의 역할은 다음과 같습니다.

  • SELECT :추출된 데이터들을 조회
  • FROM : 조회하고자 하는 테이블을 지정
  • WHERE : 테이블에서 WHERE절에서 주어진 조건에 맞는 데이터를 추출
  • GROUP BY : 데이터들끼리 묶어 구룹으로 만들어주는 구문
  • HAVING : GROUP BY에서 묶어준 그룹 중 주어진 조건에 맞는 그룹을 추출
  • ORDER BY : 추출된 데이터들을 정렬

실행 순서

쿼리를 작성하는 순서와 다르게 쿼리를 실행할 경우에는 다음과 같은 순서로 실행됩니다.

(1) FROM -> (2) WHERE -> (3) GROUP BY -> (4) HAVING -> (5) SELECT -> (6) ORDER BY

쿼리의 실행순서를 잘 이해하고 있다면 쿼리를 설계할 때 큰 도움이 됩니다.


✅ (ex : SELECT 에서 만들어진 alias 는 ORDER BY 구문에서만 사용가능, SELECT 다음으로 오는 구문은 ORDER BY 뿐이기 때문)


Syntax 설명 및 실습

  • 각 구문에 대해 SQL 문제와 정답 쿼리를 예시로 설명하도록 하겠습니다.

SELECT

  • 조회를 하길 원하는 컬럼을 지정해서 선택할 수 있는 구문.
  • *(astrick)을 사용해서 FROM 구문에서 선택한 테이블의 모든 컬럼을 지정할 수 있다.
  • DISTINCT 구문을 사용해 중복되는 컬럼값을 가지는 레코드의 중복을 제거하고 하나의 레코드만 출력할 수 있도록 지정한다.
  • 집계 함수[COUNT(),MAX(),MIN(),SUM(),AVG()]를 사용해서 GROUP BY 에서 지정된 컬럼의 통계량을 조회할 수 있다.
    -> (GROUP BY 예시에서 확인)
  • IF, CASE 등의 구문으로 특정 레코드 값을 다른 값으로 변경해서 출력할 수 있다.
    • [IF, IFNULL, ISNULL, CASE WHEN, NVL]

[Programmers] 모든 레코드 조회하기

# * 를 통해 모든 컬럼을 조회하는 쿼리
SELECT * FROM ANIMAL_INS
ORDER BY ANIMAL_ID

[Programmers] 중복제거하기

# DISTINCT 구문을 사용해서 중복되는 컬럼값을 가지는 레코드를 하나의 레코드로 출력하는 쿼리
SELECT COUNT(DISTINCT NAME)
FROM ANIMAL_INS;

[Programmers] 12세 이하의 여자 환자 목록 출력하기

# SELECT 문에 조건을 걸어 특정 조건의 값을 원하는 값으로 바꾸는 쿼리
SELECT PT_NAME, PT_NO,GEND_CD, AGE, IFNULL(TLNO,'NONE') AS TLNO
  FROM PATIENT
 WHERE GEND_CD = 'W'
   AND AGE <= 12
ORDER BY AGE DESC, PT_NAME;

[Programmers] 조건별로 분류하여 주문상태 출력하기

SELECT ORDER_ID,
       PRODUCT_ID,
       DATE_FORMAT(OUT_DATE, "%Y-%m-%d") AS OUT_DATE,
(
    CASE
    WHEN OUT_DATE <= "2022-05-01 00:00:00" THEN "출고완료"
    WHEN OUT_DATE >  "2022-05-01 00:00:00" THEN "출고대기"
    ELSE "출고미정"
    END
        
) AS '출고여부'
FROM FOOD_ORDER
ORDER BY ORDER_ID

WHERE

  • WHERE 절은 특정 컬럼의 조건에 맞는 레코드를 조회하기 위해 사용되는 구문입니다.
  • 다음과 같은 연산자를 사용해서 조건문을 제어할 수 있습니다.
    [= , >, <, >= , <=, <>(!=), BETWEEN, LIKE, IN]
  • 복합연산자를 사용해서 조회조건을 보다 정교하게 만들 수 있습니다.
    • [AND, OR, NOT]
    • OR 연산자보다 UNION ALL을 사용해 보다 효율적인 쿼리를 작성할 수 있습니다.

[Programmers] 조건에 맞는 회원 수 구하기

# WHERE 절에서 연산자의 활용 예시
# BETWEEN 과 AND 조건을 조합해서 조건에 레코드의 수를 출력하는 쿼리

SELECT COUNT(*) AS USERS
  FROM USER_INFO
 WHERE AGE BETWEEN 0 AND 29 #복합연산자 AND를 사용하는 WHERE 절
  AND YEAR(JOINED) = 2021; #BETWEEN, = 를 사용하는 WHERE 절

[Programmers] 강원도에 위치한 생산공장 목록 출력하기

# LIKE 구문을 사용해서 특정 문자열과 매칭되는 레코드를 출력하는 쿼리
SELECT FACTORY_ID, FACTORY_NAME, ADDRESS
  FROM FOOD_FACTORY
  WHERE ADDRESS LIKE "강원도%"
  ORDER BY FACTORY_ID

GROUP BY

[Programmers] 진료과별 총 예약 횟수 출력하기

SELECT MCDP_CD  AS "진료과코드",
      COUNT(MCDP_CD) AS '진료과건수'
  FROM APPOINTMENT
 WHERE APNT_YMD LIKE "2022-05%"
 GROUP BY MCDP_CD
 ORDER BY COUNT(MCDP_CD), MCDP_CD

[Programmers] 가격대 별 상품 개수 구하기

SELECT (
    CASE
    WHEN PRICE < 10000 THEN 0
    ELSE TRUNCATE(PRICE, -4)
    END
) AS PRICE_GROUP , COUNT(PRODUCT_ID)
FROM PRODUCT
GROUP BY PRICE_GROUP
ORDER BY PRICE_GROUP;

✅ 쿼리의 실행 순서에 따라 SELECT에서 선언된 PRICE_GROUP alias는 GROUP BY 구문에서 참조할 수 없습니다. 위같은 쿼리가 어떻게 가능할까요?

 

👀 MySQL과 Postgre에서는 SELECT 구문에서 정의 된 alias를 다른 구문에서 인식할 수 있는 기능을 제공합니다. 그렇기 때문에 아래와 같은 쿼리가 가능합니다. 반면, Oracle과 같은 DBMS 에서는 해당 기능을 제공하지 않습니다.

SQL - using alias in Group By


HAVING

  • group by에서 사용하는 조건문 그룹화 된 레코드 중 HAVING 절의 조건에 맞는 레코드를 찾을 수 있습니다.
  • 집계함수에 대한 조건을 걸 수 있습니다.

[Programmers] 입양 시각 구하기(1)

SELECT HOUR(DATETIME) AS HOUR,
     COUNT(HOUR(DATETIME)) AS Count
     FROM ANIMAL_OUTS
     GROUP BY HOUR
     HAVING HOUR >= 9
        AND HOUR <= 19
    ORDER BY HOUR ASC;

[Programmers] 우유와 요거트가 담긴 장바구니

SELECT A.CART_ID
FROM CART_PRODUCTS AS A
WHERE A.NAME IN ("Milk", "Yogurt")
GROUP BY A.CART_ID
HAVING COUNT(DISTINCT A.NAME) >= 2
ORDER BY A.CART_ID;

ORDER BY

  • 특정 컬럼값을 기준으로 오름차순, 내림차순 출력을 제어한다
    • [ASC, DESE]
    • ASC 는 생략 가능
  • 여러 컬럼을 기준으로 ORDER BY를 하게될 경우 앞서 등장한 컬럼을 기준으로 정렬 후 그 다음 컬럼내용을 정렬
  • SELECT 문에서 정렬할 컬럼이 없어도 지정 가능

[Programmers] 어린 동물 찾기

SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE INTAKE_CONDITION <> 'Aged'
ORDER BY ANIMAL_ID

JOIN

  • JOIN 구문을 통해 두개의 테이블을 연결하여 하나의 테이블 처럼 사용할 수 있습니다.
  • INNER JOIN, OUTER JOIN, FULL JOIN 등 여러 종류의 JOIN이 있고 각각의 구문이 테이블을 연결하는 방식을 숙지하는 것이 좋습니다.
  • 다음 그림을 통해 직관적으로 JOIN 구문을 통해 얻고자 하는 테이블의 결과를 알 수 있습니다.

JOIN의 종류

[Programmers] 있었는데요 없었습니다

SELECT A.ANIMAL_ID, A.NAME
FROM ANIMAL_INS AS A
JOIN ANIMAL_OUTS AS B
ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE A.DATETIME > B.DATETIME
ORDER BY A.DATETIME ASC;

 

[Programmers] 없어진 기록 찾기

-- 두 테이블을 OUTER JOIN을 통해 연결해서 쿼리를 작성
SELECT B.ANIMAL_ID, B.NAME
 FROM ANIMAL_INS AS A
 RIGHT OUTER JOIN ANIMAL_OUTS AS B
 ON A.ANIMAL_ID = B.ANIMAL_ID
 WHERE A.ANIMAL_ID IS NULL

 

[Programmers] 보호소에서 중성화한 동물

SELECT i.animal_id, i.animal_type, i.name
FROM animal_ins AS i 
LEFT JOIN animal_outs AS o 
ON i.animal_id = o.animal_id
WHERE i.sex_upon_intake != o.sex_upon_outcome

서브쿼리

  • 쿼리 내부에서 작성된 또 다른 쿼리문을 의미한다.
  • 쿼리 내부에서 ()로 묶여 표현된다
  • 단일 행 또는 복수 행 비교 연산자와 함께 사용이 가능하다
  • 서브쿼리에서는 ORDER BY 구문을 사용할 수 없다
  • 서브쿼리는 다음 구문내에서 사용할 수 있다.
    • SELECT
    • FROM
    • WHERE
    • HAVING
    • ORDER BY
    • INSERT문의 VALUES 부분 대체
    • UPDATE문의 SET 부분 대체
  • 서브쿼리는 또 다시 다른 서브쿼리 안에 포함될 수 있다.

[Programmers] 즐겨찾기가 가장 많은 식당 정보 출력하기

SELECT A.FOOD_TYPE,
       A.REST_ID,
       A.REST_NAME,
       A.FAVORITES
  FROM REST_INFO AS A JOIN (
  -- 서브쿼리를 사용해 가상테이블을 만드는 로직
    SELECT FOOD_TYPE, MAX(FAVORITES) AS FAVORITES
      FROM REST_INFO
     GROUP BY FOOD_TYPE
  ) B
  ON A.FOOD_TYPE = B.FOOD_TYPE AND A.FAVORITES = B.FAVORITES
ORDER BY FOOD_TYPE DESC

 

[참고]

https://yoongeons.com/entry/SQL-문법-정리

https://velog.io/@ynjch97/SQL-효율적인-SQL-쿼리-튜닝-방법
https://donghak-dev.tistory.com/156
https://kimsoungryoul.tistory.com/55

'Computer Science > Database' 카테고리의 다른 글

[DB] JPA(Java Persistence API) 란 무엇인가?  (0) 2022.12.21
[DB] 정규화(Normalization)에 대해서  (0) 2022.12.20
    'Computer Science/Database' 카테고리의 다른 글
    • [DB] JPA(Java Persistence API) 란 무엇인가?
    • [DB] 정규화(Normalization)에 대해서
    Becker
    Becker

    티스토리툴바