ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [DB] SELECT 문으로 데이터 조회하기 (Basic Retrieval Queries in SQL)
    DB 2025. 10. 18. 20:22

     

     

    지난 포스팅에서 테이블을 만들고 제약조건으로 구조를 정의했다면, 이제부터는 그 안에 들어 있는 데이터를 조회(Query) 하는 법을 알아보자.

     

    SQL의 진짜 힘은 "원하는 데이터를 정확히 꺼내오는 능력"에 있다. 그 핵심이 바로 SELECT 문이다.

     

     

     


     

    SQL에서 데이터 조회의 기본 구조

    SQL에서 데이터를 가져올 때 사용하는 명령은 바로 SELECT 문이다. 모든 SELECT 문은 다음과 같은 기본 형태를 가진다.

     

    SELECT <attribute list> 
    FROM <table list>
    WHERE <condition>;

     

    예를 들어,

    SELECT Name 
    FROM Employee 
    WHERE Age >= 20;

     

    이 쿼리는 "20세 이상인 직원의 이름을 가져와라"는 의미다.

     

     

    SELECT–FROM–WHERE 구조 

    SELECT 문은 크게 세 부분으로 구성된다.

     

    역할 대응되는 관계대수 연산
    SELECT 가져올 속성(컬럼)을 지정 <attribute list> Projection
    FROM 데이터를 가져올 테이블을 지정 <table list> Relation
    WHERE 조건을 지정 <condition> Selection
    • SELECT: 무엇을 볼지
    • FROM: 어디서 가져올지
    • WHERE: 어떤 조건을 만족해야 하는지

     

    SQL은 비절차적(non-procedural), 선언적(declarative) 언어다. "어떻게 가져올지"가 아니라 "무엇을 원한다"를 선언한다. 실행 계획은 DBMS가 알아서 최적화한다.

     

     


     

     

    1. 단일 테이블 조회 (Simple SELECT)

    SELECT Bdate, Address
    FROM EMPLOYEE
    WHERE Fname = 'John' AND Lname = 'Smith';

     

    → "이름이 John Smith인 직원의 생년월일과 주소를 조회하라." 

    WHERE 절은 조건 필터링 역할을 한다.

     

     

    2. 두 테이블 JOIN (2-way Join)

    SELECT E.Fname, E.Lname, D.Dname
    FROM EMPLOYEE E, DEPARTMENT D
    WHERE E.Dno = D.Dnumber AND D.Dname = 'Research';

    Research 부서에서 일하는 직원의 이름과 부서명을 가져온다.

     

    이건 SQL의 대표적인 select–project–join (SPJ) 패턴이다. E.Dno = D.Dnumber 가 바로 두 테이블을 연결하는 조인 조건(join condition) 이다.

     

     

    3. 세 테이블 JOIN (3-way Join)

    SELECT P.Pnumber, P.Dnum, E.Lname, E.Address, E.Bdate
    FROM PROJECT P, DEPARTMENT D, EMPLOYEE E
    WHERE P.Dnum = D.Dnumber  -- join betwwen PROJECT and DEPARTMENT
      AND D.Mgr_ssn = E.Ssn   -- join between DEPARTMENT and EMPLOYEE
      AND P.Plocation = 'Stafford';

    → Stafford 지역의 프로젝트 번호, 부서 번호, 부서장의 이름, 주소, 생년월일을 조회한다.

     

     

    같은 이름의 속성 구분 (Ambiguous Attributes)

    서로 다른 테이블에 같은 컬럼 이름이 있을 경우 테이블 이름 또는 별칭(alias) 을 붙여야 한다.

    SELECT E.Name, D.Name
    FROM EMPLOYEE E, DEPARTMENT D
    WHERE E.Dno = D.Dnumber;

     

    여기서 E.Name은 직원 이름, D.Name은 부서 이름이다.

    이런 식으로 "table.attribute" 형식으로 쓰는 걸 fully qualified name이라고 부른다.

     

     

    별칭(Alias)과 Renaming

    같은 테이블을 두 번 참조할 때는 반드시 별칭이 필요하다.

    직원과 그 상사의 이름을 한 번에 조회하는 경우:

    SELECT E.Fname AS Emp_Fname, S.Fname AS Sup_Fname
    FROM EMPLOYEE E, EMPLOYEE S
    WHERE E.Super_ssn = S.Ssn;
    • E는 직원(Employee)
    • S는 상사(Supervisor)

    AS는 선택사항이며, 생략해도 된다 (E.Fname Emp_Fname 가능).

     

     

    WHERE 절이 없는 경우

    SELECT Ssn, Dname FROM EMPLOYEE, DEPARTMENT;

    WHERE 절이 없으면, DBMS는 두 테이블의 모든 가능한 행 조합(Cartesian Product)을 만들어낸다.

    즉, EMPLOYEE의 각 행이 DEPARTMENT의 모든 행과 연결되며, 결과 행 수는 N × M이 된다.

     

     

     

     

    SELECT * 모든 컬럼 가져오기 (Asterisk)

    SELECT * FROM EMPLOYEE;

     

    모든 속성을 전부 가져올 때 사용한다. 또는 아래와 같이 특정 테이블의 모든 컬럼만 가져올 수도 있다

    SELECT E.*, D.Dname
    FROM EMPLOYEE E, DEPARTMENT D
    WHERE E.Dno = D.Dnumber;

     


     

     

    SQL은 "중복 제거"를 자동으로 하지 않는다

    SQL에서 테이블은 수학적인 "집합(set)"이 아니라, 중복된 행(튜플)을 허용하는 멀티셋(multiset, bag) 이다.


    즉, 같은 데이터가 여러 번 존재할 수 있다. 중복 제거는 자동으로 수행되지 않으며, 필요할 때만 DISTINCT를 사용한다.

     

     

     

    중복 제거: DISTINCT

    중복을 제거하려면 DISTINCT 키워드를 사용한다.

    SELECT DISTINCT Dno FROM EMPLOYEE;

     

    중복 제거(DISTINCT)는 비용이 크다. 내부적으로 정렬(SORT) 또는 해싱(HASH)이 필요하기 때문이다.

    또한 사용자가 중복된 튜플 값을 보고싶을 수도 있다. 특히 집계 함수가 적용된 튜플일수록 대부분의 예시에서는 중복 제거를 원하지 않는다.

    그래서 SQL은 기본적으로 "중복 허용(multiset)"이 기본값이다.

     

     

    집합 연산 (Set Operations)

    SQL은 결과 집합끼리의 연산을 지원한다. UNION, INTERSECT, EXCEPT 세 가지가 대표적이다.

    연산 (중복제거) 의미 중복 허용 버전 (Multiset operation)
    UNION 합집합 UNION ALL
    INTERSECT 교집합 INTERSECT ALL
    EXCEPT 차집합 EXCEPT ALL

    두 결과를 합치려면 컬럼 수와 데이터 타입이 일치해야 한다.

    (SELECT Ssn FROM EMPLOYEE)
    UNION
    (SELECT Essn FROM DEPENDENT);

     

     

     

     

     

    “Make a list of all project numbers for projects that involve an employee whose last name is ‘Smith’, either as a worker or as a manager of the department that controls the project.”

     

     


     

     

    문자열 패턴 매칭: LIKE

    SQL은 LIKE 연산자를 사용해 부분 문자열 검색을 지원한다.

    % 0개 이상의 임의 문자열
    _ 정확히 1개의 문자
    SELECT * FROM EMPLOYEE
    WHERE Address LIKE '%Houston%';

    “Houston”이 들어간 주소를 가진 직원 조회.

     

    SELECT * FROM EMPLOYEE
    WHERE Fname LIKE '_a%';

    두 번째 글자가 'a'인 이름(예: Mary, Jake 등)

     

     

    %나 _ 자체를 찾고 싶을 땐 ESCAPE 문자를 지정해 예외처리할 수 있다.

     

     

     


     

     

    산술 연산 (Arithmetic Operations)

    SELECT 문에서도 계산식을 사용할 수 있다.

    SELECT Fname, Lname, Salary, Salary * 1.1 AS Increased_Salary
    FROM EMPLOYEE
    WHERE Dno = 5;

    -> 부서 5번 직원들의 급여를 10% 인상한 결과 계산

     

     

    BETWEEN: 범위 비교

    범위 조건을 간단히 표현할 때 BETWEEN을 사용한다.

    SELECT *
    FROM EMPLOYEE
    WHERE Salary BETWEEN 3000 AND 5000;

     

    3000 이상 5000 이하의 급여를 가진 직원 조회. (BETWEEN은 양 끝값도 포함한다 -> inclusive range)

     

     

    ORDER BY: 정렬

    조회 결과를 정렬하려면 ORDER BY를 사용한다.

    SELECT Fname, Lname, Salary
    FROM EMPLOYEE
    ORDER BY Salary DESC;

     

    ASC는 오름차순(기본값), DESC는 내림차순을 의미한다.

     

     

    복수 기준 정렬도 가능하다

    ORDER BY Dno ASC, Salary DESC;

    -> 부서 번호 오름차순, 급여 내림차순

     

     


     

    정리: Basic SQL Query 구조


    SELECT 가져올 컬럼 지정 SELECT Fname, Lname
    FROM 데이터 소스 지정 FROM EMPLOYEE, DEPARTMENT
    WHERE 조건 지정 WHERE Dno = Dnumber
    DISTINCT 중복 제거 SELECT DISTINCT Dno
    UNION / INTERSECT / EXCEPT 집합 연산 UNION ALL
    LIKE 문자열 검색 LIKE '%Seoul%'
    BETWEEN 범위 비교 BETWEEN 3000 AND 5000
    ORDER BY 정렬 ORDER BY Salary DESC

     

    이번 장에서는 SQL의 조회 구문(SELECT-FROM-WHERE) 와 그 확장 기능들을 모두 살펴봤다.

    결국 SQL의 중심에는 SELECT 문이 있다. "무엇을, 어디서, 어떤 조건으로" 조회할지를 선언하면, DBMS는 그에 맞는 최적의 실행 계획을 자동으로 찾아낸다.

     

     

     

     

    출처: 경북대학교 이천희 교수님, “데이터베이스” 강의 자료

Designed by Tistory.