본 시리즈에서는 데이터베이스의 개념을 정리하고 필요시 실습을 진행합니다.
Ubuntu-24.04
)10.11.8-MariaDB
)2024.2.2
)correto-21
)Ultimate Edition
)world database
View(뷰)는 가상 테이블로, 실제 데이터를 저장하지 않고 기존 테이블에서 생성한 쿼리 결과를 저장하여 사용합니다.
View
는 데이터가 아닌 쿼리의 결과를 기반으로 만들어진 가상의 테이블입니다.View
로 정의하여 쉽게 재사용할 수 있습니다.기존 city
테이블에서 인구가 9,000,000
이상인 도시만 포함된 View
를 생성한다고 가정해보겠습니다.
View
생성# view 생성
CREATE VIEW large_cities AS
SELECT Name, CountryCode, Population
FROM city
WHERE Population > 9000000;
View
조회# view 조회
SELECT * FROM large_cities;
View
삭제# view 삭제
DROP VIEW large_cities;
View
는 보고서나 특정 사용자에게 데이터를 제한적으로 제공해야 할 때 유용합니다.
Dual Table은 Oracle
에서 주로 사용하는 임시 테이블로, 쿼리에 실제 테이블이 필요하지 않을 때 사용됩니다.
MySQL
혹은 MariaDB
에서는 Dual Table
을 사용할 필요는 없지만, 호환성이나 다른 데이터베이스 환경을 고려할 때 Dual Table
의 개념을 이해해두는 것이 좋습니다.Oracle
에서만 필수적으로 사용되며, MySQL/MariaDB
에서는 생략 가능합니다. MySQL/MariaDB
에서는 명시적으로 사용해도 큰 문제가 되지 않습니다.Dual
테이블을 사용하여 상수 값을 반환할 수 있습니다.SELECT 1 FROM DUAL;
Dual
테이블을 사용하여 함수를 테스트하거나 간단한 계산을 수행할 수 있습니다.SELECT NOW() AS CurrentDate FROM DUAL;
MySQL(MariaDB)
에서는 Dual 테이블
없이도 동일한 쿼리를 실행할 수 있습니다. 예를 들어, 아래와 같이 테이블을 생략할 수 있습니다.SELECT NOW() AS CurrentDate;
NOW()
와 같은 날짜 함수를 실행하여 현재 시간을 확인하거나, PI()
와 같은 수학 함수를 테스트할 때 사용합니다.SQL 내장 함수는 데이터베이스 벤더(Oracle
, MySQL
등)에서 기본적으로 제공하는 함수로, SQL 쿼리에서 데이터 조회와 분석을 쉽게 할 수 있게 도와줍니다.
내장 함수는 크게 두 가지로 구분됩니다:
문자형
, 숫자형
, 날짜형
함수 등이 여기에 해당합니다.집계
함수와 그룹
함수가 대표적이며, SUM
, AVG
, COUNT
등이 포함됩니다.단일행 함수는 하나의 행
을 입력으로 받아 해당 행에 대한 결과를 반환하는 함수입니다.
함수 | 설명 | 예제 |
---|---|---|
UPPER() | 문자열을 대문자로 변환 | UPPER('hello') → 'HELLO' |
LOWER() | 문자열을 소문자로 변환 | LOWER('HELLO') → 'hello' |
CONCAT() | 여러 문자열을 하나로 결합 | CONCAT('Hello', ' ', 'World') → 'Hello World' |
SUBSTRING() | 문자열의 일부를 추출 | SUBSTRING('Hello', 1, 3) → 'Hel' |
LENGTH() | 문자열의 길이를 반환 | LENGTH('Hello') → 5 |
TRIM() | 문자열 양 끝의 공백을 제거 | TRIM(' Hello ') → 'Hello' |
REPLACE() | 문자열 내 특정 문자를 다른 문자로 대체 | REPLACE('Hello World', 'World', 'SQL') → 'Hello SQL' |
함수 | 설명 | 예제 |
---|---|---|
ROUND() | 지정된 자릿수로 반올림 | ROUND(123.456, 2) → 123.46 |
ABS() | 절대값 반환 | ABS(-10) → 10 |
CEIL() | 주어진 값보다 큰 가장 작은 정수 반환 | CEIL(10.2) → 11 |
FLOOR() | 주어진 값보다 작은 가장 큰 정수 반환 | FLOOR(10.8) → 10 |
POWER() | 지정된 거듭제곱 계산 | POWER(2, 3) → 8 |
MOD() | 두 숫자 간의 나머지 반환 | MOD(10, 3) → 1 |
함수 | 설명 | 예제 |
---|---|---|
NOW() | 현재 날짜와 시간 반환 | NOW() → 2023-05-12 10:30:00 |
DATE_ADD() | 날짜에 지정된 기간을 더함 | DATE_ADD('2023-05-12', INTERVAL 10 DAY) → '2023-05-22' |
DATEDIFF() | 두 날짜 간의 차이 일수 반환 | DATEDIFF('2023-05-22', '2023-05-12') → 10 |
YEAR() | 날짜에서 연도를 추출 | YEAR('2023-05-12') → 2023 |
DATE_FORMAT() | 날짜를 지정된 형식으로 변환 | DATE_FORMAT('2023-05-12', '%Y/%m/%d') → '2023/05/12' |
STR_TO_DATE() | 문자열을 날짜 형식으로 변환 | STR_TO_DATE('12-05-2023', '%d-%m-%Y') → '2023-05-12' |
함수 | 설명 | 예제 |
---|---|---|
CAST() | 데이터 타입을 변환 | CAST('123' AS INT) → 123 |
CONVERT() | 데이터 타입을 변환 | CONVERT('123', SIGNED) → 123 |
FORMAT() | 숫자를 지정된 문자열로 변환 | FORMAT(1234567.8912, 2) → '1,234,567.89' |
함수 | 설명 | 예제 |
---|---|---|
IFNULL() | NULL일 경우 대체값 반환 | IFNULL(NULL, 'default') → 'default' |
COALESCE() | NULL이 아닌 첫 번째 값 반환 | COALESCE(NULL, NULL, 'value') → 'value' |
다중행 함수는 여러 행의 값
을 입력으로 받아 하나의 결과를 반환하는 함수로, 주로 집계 함수라고도 불립니다. 그룹화된 데이터의 요약 정보를 얻는 데 유용합니다.
함수 | 설명 | 예제 |
---|---|---|
SUM() | 값의 합계 반환 | SUM(salary) |
AVG() | 값의 평균 반환 | AVG(age) |
COUNT() | 행의 개수 반환 | COUNT(*) |
MAX() | 최대값 반환 | MAX(salary) |
MIN() | 최소값 반환 | MIN(salary) |
서브쿼리(Subquery)는 SQL에서 쿼리 내에 포함된 또 다른 쿼리입니다.
SELECT
, FROM
, WHERE
, HAVING
등의 절에서 주로 사용됩니다.서브쿼리는 결과를 반환하여 메인 쿼리의 조건이나 값으로 사용되며, 쿼리를 단계별로 실행할 수 있는 유연성을 제공합니다.
하나의 값만 반환
하여 메인 쿼리에서 단일 값을 비교할 때 사용됩니다.여러 행을 반환
하며, 메인 쿼리의 IN
, ANY
, ALL
조건과 함께 사용됩니다.SELECT
, FROM
, WHERE
, HAVING
절 등에 위치할 수 있으며, 상황에 따라 다양한 방식으로 사용됩니다.SELECT 절에서의 서브쿼리
SELECT
절에서 서브쿼리를 사용하여 특정 열에 대한 계산 결과를 반환할 수 있습니다.
예제 : 각 나라의 수도 이름을 조회하고, 각 수도의 도시 인구 수를 함께 조회
SELECT country.Name AS Country, (SELECT city.Name FROM city WHERE city.ID = country.Capital) AS Capital, (SELECT Population FROM city WHERE city.ID = country.Capital) AS CapitalPopulation FROM country;
FROM 절에서의 서브쿼리
FROM
절에 서브쿼리를 사용하여 임시 테이블을 생성하고, 이를 메인 쿼리의 데이터 원본으로 사용할 수 있습니다.
예제: 각 대륙별로 인구가 가장 많은 국가와 그 인구 수를 조회
SELECT subquery.Continent, country.Name AS LargestCountry, subquery.MaxPopulation FROM ( SELECT Continent, MAX(Population) AS MaxPopulation FROM country GROUP BY Continent ) AS subquery JOIN country ON country.Continent = subquery.Continent AND country.Population = subquery.MaxPopulation;
WHERE 절에서의 서브쿼리
WHERE
절에서 서브쿼리는 특정 조건을 지정하는 데 유용하며, 메인 쿼리의 필터링 조건으로 사용할 수 있습니다.
예제:
country
테이블에서 인구가 전체 평균 인구 이상인 국가를 조회SELECT Name, Population FROM country WHERE Population >= (SELECT AVG(Population) FROM country);
HAVING 절에서의 서브쿼리
HAVING
절에서 서브쿼리는 그룹화된 결과에 대해 조건을 지정할 때 유용합니다.
예제: country 테이블에서 각 대륙별로 평균 인구보다 인구가 많은 국가 조회
SELECT Continent, Name, Population
FROM country
GROUP BY Continent, Name
HAVING Population > (SELECT AVG(Population) FROM country WHERE country.Continent = Continent);
HAVING
절은 주로 집계 함수의 결과에 조건을 걸 때 주로 사용됩니다.HAVING
절은 그룹화된 데이터에 대해 집계 함수로 계산된 결과에 조건을 추가할 때 최적화되어 있기 때문에, 서브쿼리가 들어가면 성능상 비효율적일 수 있습니다.WHERE
절에서 사용하는 것이 일반적이며, HAVING
절에서 서브쿼리를 사용하는 경우는 많지 않습니다. HAVING
절에 서브쿼리를 사용해야 하는 상황이라면, 쿼리를 재구성하거나 WHERE
절을 활용할 방법을 고려하는 것이 좋습니다.상관 서브쿼리(Correlated Subquery)는 메인 쿼리의 각 행에 대해 서브쿼리가 실행되는 방식으로, 메인 쿼리와 서브쿼리가 서로 상호 참조합니다. 상관 서브쿼리는 메인 쿼리와 서브쿼리가 상호 종속적으로 실행됩니다.
예제: country
테이블에서 자신의 대륙에서 인구가 가장 많은 국가 조회
SELECT Name, Population, Continent
FROM country AS c1
WHERE Population = (
SELECT MAX(Population)
FROM country AS c2
WHERE c2.Continent = c1.Continent
);
EXISTS
는 서브쿼리가 결과를 반환하는지 여부를 확인하며, 서브쿼리가 결과를 반환하면 TRUE, 그렇지 않으면 FALSE를 반환합니다. 주로 조건을 효율적으로 필터링할 때 사용됩니다.
예제: city
테이블에 도시가 있는 국가만 조회
SELECT Name
FROM country
WHERE EXISTS (SELECT 1 FROM city WHERE city.CountryCode = country.Code);
이번 포스팅에서는 SQL 내장 함수와 서브쿼리에 대해 깊이 있게 다루었습니다.
특히 서브쿼리를 사용할 때는 가독성과 성능 최적화에 유의해야 합니다.
JOIN
을 사용하여 대체하거나 WHERE
절을 활용하는 것이 더 효율적일 수 있습니다. 다음 포스팅에서는 SQL에서 로직을 구현하는 조건문(CASE문)과 사용자 정의 함수, 프로시저, 트리거에 대해 다룰 예정입니다.