[SQL 시작] 10. 데이터 쿼리

표준 SQL 및 데이터베이스 입문

by AI개발자
gaebalai-sql-db (1).jpg

테이블을 생성하고 데이터를 등록하면, 이제 본격적으로 쿼리를 해봅시다. SELECT문중 가장 단순한 쿼리부터 확인해 봅시다.


데이터를 취득하는 절차나 명령을 '질의(query, 쿼리)'라고 합니다. SQL에서는 SELECT문으로 이를 수행합니다. 이번부터는 샘플 데이터베이스 examdb의 테이블을 사용합니다. 테이블 구성은 아래와 같습니다. 이런 구성이 이루어진 이유는 나중에 따로 설명합니다.


branch_master와 course_master는 각각 캠퍼스와 과목을 등록할 때 참조되는 테이블이며, 이번 SELECT문에서는 students와 courses라는 2개 테이블을 사용합니다.

테이블 개요 및 관계는 아래에서 제시합니다.


examdb테이블 구성

sql015-1.png


⑴ 테이블표시 (쿼리①)

우선 기본중의 기본인 테이블을 표시하는 방법을 알아봅시다. 'SELECT 열명 FROM 테이블명 WHERE 조건'입니다. 여기서 'SELECT 열명'부분은 SELECT절, 'FROM 테이블명' 부분은 FROM절, 그리고 'WHERE 조건'부분은 WHERE절이라고 부릅니다.


그런데, WHERE절에서 지정하는 열은 SELECT절에서 반드시 지정할 필요가 없다는 사실을 알고 있나요? 어떤 열을 가져올지와 어떤 열로 범위를 한정할지는 별도로 지정할 수 있습니다.


테이블의 데이터를 표시하려면, 'SELECT 열명 FROM 테이블명 WHERE 조건'과 같이 지정합니다. 만약, SELECT에서 지정할 열이 여러 개라면 표시하고자 하는 순서대로 '열1, 열2, 열3, ...'와 같이 쉼표(,)로 구분하여 나열할 수 있습니다. 또한, '모든 열'을 의미하는 '*'를 지정할수도 있습니다.


참고로 WHERE절에서 사용한 열을 반드시 SELECT절에 지정할 필요는 없습니다. SELECT절에서는 오로지 표시하고자 하는 열만 지정하면 됩니다. 그리고 WHERE절이 없는 경우에는 테이블의 모든 행이 대상이 됩니다.


이와 같이 SELECT로 시작하는 SQL문은 'SELECT문(SELECT statement)'이라고 부릅니다. SELECT문은 일반적으로 열을 지정하는 SELECT절(SELECT claude), 테이블을 지정하는 FROM절(FROM clause), 조건을 지정하는 WHERE절(WHERE claude)로 구성됩니다. 이처럼 SQL문(statement)을 구성하는 한 덩어리를 '절(claude)' 또는 '구절(claude)'이라고 부릅니다.


각 테이블의 개요와 테이블의 관계

sql016.jpg


조건을 지정하지 않고 모든 것을 표시

sql016-1.png
sql017.jpg


WHERE에 지정된 조건과 일치하는 행만 표시

sql018.png
sql0181.jpg


⑵ 데이터 재정렬 (쿼리②)

여기서 중요한 것을 우선 말하자면, 데이터의 순서에 대한 것입니다. 표시순서로서 위 예제를 실행한 결과를 보면, student_id기준 순서로 되어 나온 결과같다고 느끼고 있겠지만, 사실 그렇게 정렬되는 것은 보장이 안됩니다. 보통은 주키(Primary Key)나 테이블을 조인할 경우, 조인 조건에 사용된 열의 순서대로 정렬되는 경우가 많지만 이 순서를 유지하고 싶다면 ORDER BY를 지정해야 합니다.


데이터정렬은 ORDER BY 열명으로 지정합니다. 여러 열의 조합으로 정렬하고자 할 경우에는 'ORDER BY 열명1, 열명2'와 같이 쉼표(,)로 구분하여 나열합니다. 이 경우 우선 지정한 열이 우선됩니다.

또한, 정렬에는 오름차순(작은 값을 먼저)과 내림차순(역순, 큰 값을 먼저)을 지정할 수 있으며, 오름차순은 'ORDER BY 열명 ASC', 내림차순은 'ORDER BY 열명 DESC'로 지정합니다. 기본정렬 순서는 오름차순(ASC)입니다.


아래의 ①과 ②는 동일한 조건의 SELECT문으로,

①은 학생이 다니는 중학교를 등록하고 있는 school열의 순서대로 정렬하는 예제이고,

②는 student_id의 내림차순으로 정렬하는 예제를 보여줍니다.


① school 순서로 정렬

sql018-1.png
sql019.png 총 47건

② student_id 내림차순으로 정렬

sql019-1.png
sql020.png 총 47건


⑶ 데이터 집계 (쿼리③)

데이터 건수를 조사할 경우, 조건에 맞는 데이터가 몇건인지, 또는 캠퍼스별로 몇 명인지등을 알아보고 싶을 때, COUNT()함수를 사용합니다. 'OO마다'라는 조건이라면 추가로 GROUP BY와 결합하여 사용합니다.


데이터의 건수나 평균값 등은 '집계합수(aggregate function, 집합함수)'를 사용하여 구할 수 있습니다. 예를 들어, '해당 데이터의 건수'는 'SELECT COUNT(*) FROM 테이블명 WHERE 조건'처럼 지정합니다.

sql020-1.png
sql021.png

만약, 'OO마다'와 같이 그룹단위의 건수를 구하고자 하는 경우, WHERE절 뒤에 GROUP BY 열명으로 지정합니다. 아래 예제에서는 WHERE절이 없으므로, FROM절 뒤에 GROUP BY 절을 지정합니다. GROUP BY절에서 여러 열을 지정하고자 할 경우에는 쉼표(,)로 구분하여 나열합니다. 실제 사용하는 예제는 아래를 참고합니다.

또한, GROUP BY가 지정된 경우, SELECT절에 쓸 수 있는 것은 GROUP BY에서 지정한 열명 또는 집계합수만이며, 집계함수로 지정할 수 있는 열은 GROUP BY에서 지정한 열명 또는 '*'만 사용할 수 있습니다.

sql021-1.png
sql022.png


⑷ 집계결과별로 정렬 (집계정렬①)

집계도 간단합니다. 그런데 이 결과를 기준으로 정렬하려면 어떻게 해야할까요? 이 경우 ORDER BY를 사용하면 됩니다. 건별로 정렬하고 싶은 경우, GROUP BY 이후에 'ORDER BY COUNT(*)'를 지정합니다.

sql022-1.png
sql022-2.png
sql023.png
sql024.png


⑸ 다른 열명으로 표시 (집계정렬②)

① 결과의 컬럼명이 'COUNT(*)'라고 표시된 것을 '인원수'라고 표시하고 싶을 경우 COUNT뿐만 아니라, 다른 열에 별칭을 부여해서 표시할 때, AS를 사용하면 됩니다.


'열명 AS 별칭'으로 SELECT문의 결과로 표시되는 열명에 별칭(alias)을 부여할 수 있습니다①. SELECT절에서 부여한 별칭은 GROUP BY 절이나 ORDER BY절에서도 사용할 수 있습니다.②③

sql024-1.png
sql024-2.png
sql024-3.png
sql027.png
sql026.png
sql025.png


⑹ 테이블 조인 (쿼리④)

이제 테이블을 늘려봅시다. 이런 경우를 결합(조인)이라고 합니다. 이때 JOIN을 사용합니다.

테이블을 결합하는 경우 '결합(JOIN)'이라고 하며, 'SELECT 열명 FROM 테이블1 JOIN 테이블2 ON 결합조건'과 같이 지정합니다. 예를 들어, 선택과목이 저장되어 있는 courses테이블과 학생명등이 저장되어 있는 students테이블을 결합하여 모든 열을 표시하는 경우는 다음과 같이 합니다. 이 예제에서는 우선 courses테이블의 열이 표시되고, 그 다음에 students테이블 열이 표시됩니다.

sql025-1.png
sql028.png 총 283건

SELECT절에서 열을 지정할 때는 해당 열이 어느 테이블의 열인지 명확하게 표시해야 합니다. 예를 들어, 'student_id'는 두 테이블 모두에 존재하므로 '테이블명.student_id'와 같이 테이블명을 붙여야 합니다. 이번의 경우, student_id는 결합조건으로 사용되며, 'students.student_id'와 'courses.student_id'에는 동일한 값이 들어 있을 것입니다. 따라서 어느 이름을 사용해도 결과는 동일합니다.

또한, 'student_name'이나 'course'는 한쪽 테이블에만 존재하므로 테이블명을 지정할 필요는 없지만, 지정해도 상관없습니다. 아래 2개의 SELECT문은 동일한 결과를 반환합니다. 복잡한 테이블 구조이거나 3개이상의 테이블을 결합하는 경우, 각 열이 어느 테이블에 속하는지를 모두 명시해 두면 향후 유지보수에 큰 도움이 됩니다.

sql028-1.png
sql028-2.png
sql029.png 총 283건


⑺ 결합된 결과를 좁히고 정렬하기 (결합①)

결합된 결과나 필터링하거나 정렬할 수 있을까? 동일합니다. WHERE와 ORDER BY를 사용합니다.

'JOIN ~ ON'구문 뒤에도, WHERE절이나 ORDER BY절을 붙일 수 있습니다. 여기서 사용하는 열도 필요에 따라 테이블명을 명시합니다. 다음 예제에서는 앞서 courses테이블과 students테이블을 결합한 결과에 WHERE절로 서초구 캠퍼스만 지정하고, ORDER BY절로 course순으로 정렬하는 조건을 추가하고 있습니다.

sql029-1.png
sql030.png 총 119건

course별 데이터순서는 환경에 따라 다르기 때문에 일정하게 만들려면 ORDER BY student_id를 추가합니다.



⑻ 결합된 결과를 집계하기 (결합②)

결합된 결과도 필터링이나 정렬할 수 있을까? 동일하게 WHERE와 ORDER BY를 사용하면 됩니다.

COUNT와 GROUP BY도 같은 방식으로 지정할 수 있으며, 다음 SELECT문은 '캠퍼스와 과목별 인원수를 집계하는' 것으로 courses와 students를 결합한 결과를 과목별로 집계하고 건수가 적은 순서로 정렬하고 있습니다.

sql030-1.png
sql031.png

아래 열로 집계할 경우, 'GROUP BY 열1, 열2...'와 같이 쉼표(,)로 구분하여 지정합니다. 아래 SELECT문에서는 courses와 students를 결합한 결과를 각 branch에 대대 course별로 집계하고 있습니다. 또한, 정렬순서도 branch와 course순으로 지정했습니다.

sql031-1.png
sql032.png

송파구 캠퍼스에는 국어 과목을 선택한 학생이 없다는 것입니다. 현재는 송파구 캠퍼스는 영어와 수학만 선택한 학생만 있습니다.

송파구 캠퍼스에는 우연히 국어를 선택한 학생이 존재하지 않는 것인지, 아니면 존재하면 안되는 것인지, 어느쪽일지... 만약, '송파구 캠퍼스는 영어와 수학만 있다'는 규칙이 있다면, 테이블도 그렇게 설계하는 것이 좋을수도 있으며, 이 부분에는 나중에 다시 검토하겠습니다.



©2024-2025 GAEBAL AI, Hand-crafted & made with Damon JW Kim.

GAEBAL AI 개발사: https://gaebalai.com

AI 강의 및 개발, 컨설팅 문의: https://talk.naver.com/ct/w5umt5


keyword
이전 09화[SQL 시작] 9. 데이터 삭제