SQL과 RDB란 무엇인가
1. SQL 학습 목적
데이터로 data product(데이터 분석 레포트, 특정 역할 수행하는 머신러닝 모델 등 : 데이터 사이언트스트/분석가가 데이터로 만들어내는 다양한 산출물)을 만들기 위해서
DB에서 원하는 데이터 가져올 때 SQL 사용함
1. 원하는 형태로 데이터를 가져올 수 있다.
2. 효율적인 데이터를 가져올 수 있다.
3. 간단히 데이터 분석을 수행할 수 있다.
2. RDBMS/SQL 개요
DB는 데이터를 쌓아놓는 곳, 데이터의 묶음임
- 관계형 데이터베이스(Relational DB, RDBMS)
- MySQL, Oracle 등
- 비관계형 데이터베이스(Not Only SQL, NoSQL)
- Key-value Store
- Column-family
- Document
- Graph
- 관계형 데이터베이스(RDBMS)
- 사용 목적
- 정형 데이터 : 테이블/행/열(표)로 이루어진 형태
- Transaction 처리 : 데이터의 일관성과 무결성이 중요한 금융 정산 서비스 등에서 사용
- Transaction : DB 상태를 변화시키는 논리적 실행 단위 : 데이터를 쓰거나, 수정하거나, 삭제하는 등의 상태 변환. 계좌이체 시 보낸 사람은 빼고, 받는 사람은 더하고. 이게 한 트랜잭션에 대해 일어남
- 데이터 일관성 : DB에서 트랜잭션이 안전하게 수행되는 것을 보장하기 위한 성질
- ACID(Atomicity, Consistency, Isolation, Durability)
- 스키마 : DB 내에서 데이터가 어떤 구조로 저장되어 있는지 나타냄
- 데이터 구조 변경이 어려울 수 있음
- 수평 확장(Scale out)이 복잡하고 어려움
- 사용 목적
- 비관계형 데이터베이스(NoSQL)
- 사용목적
- 비정형/반정형 데이터 : JSON, XML 등 다양한 형태
- 대량의 데이터와 빠른 읽기/쓰기
- 데이터 일관성 : DB마다 다르고 ACID 특성을 보장하지 않는 경우도 있고 중복이 발생함
- 스키마 : 스키마가 없거나 유연함. 데이터 모델을 사용해 데이터 구조를 자유롭게 변경 가능함
- 쿼리언어 : DB마다 고유한 쿼리 언어 또는 API를 제공하며 SQL과는 다른 방식으로 데이터를 질의
- 수평 확장이 상대적으로 용이함
- 사용목적
SQL(Structed Query Language) : 관계형 데이터베이스를 사용하기 위한 표준 언어
데이터가 하나 이상의 열, 행과 관계를 맺고 있기 때문에 관계형 데이터베이스임
데이터 조회 : SELECT, FROM, WHERE
- SQL 기초 구문
SQL문=SQL 쿼리
쿼리(Query) : 질의하다
관계형데이터베이스에 정해진 형식대로 질의하면 RDBMS가 질의에 맞는 형태의 데이터를 돌려준다.
DB Fiddle - SQL Database Playground
www.db-fiddle.com
SQL을 웹사이트에서 사용할 수 있고 테이블 시각화 가능
- 데이터 조회
SQL Query에서 기본 뼈대가 되는 것은 3가지임
SELECT, FROM, WHERE
- SELECT : 무엇을 가져올지 지정(테이블에서 원하는 컬럼을 가져오는 역할)
- FROM : 어디에서 가져올지 지정
- 테이블이 여러 개일 경우 어디서 가져올지도 지정
- WHERE : 어떤 조건으로 가져올지 지정
- WHERE 이하 조건에 일치하는 경우만 가져옴
- 행을 선택하기 위한 목적
모든 컬럼 가져오고 싶을 시 SELECT *
테이블이 커서 열과 행이 많을 경우 불필요한 많은 리소스 사용이 가능해 비추천
WHERE 문은 WHERE 이하의 조건들을 만족하는 것들을 가져옴
WEHRE 문에서는 다양한 비교연산자, 논리연산자를 이용해서 조건을 정할 수 있음
WHERE 바로 뒤에 어떤 조건이 있다면, 그걸 빼려고 할 때/삽입하려고 할 때 귀찮아짐
필터링 시 WHERE은 필수인데, 같은 줄에 있는 걸 빼려면 바로 아래 조건을 위로 올려 WHERE 위로 놔야 하기 때문이다.
그래서 WHERE 1=1이면, WHERE 문 아래에 다른 조건이 있을 때 수정할 필요가 없어짐!
# 데이터 조회 : WHERE
SELECT product_id, category
FROM products
WHERE 1=1
AND category='주방용품'
AND price > 5000
WHERE 1=1 하는 경우는 AND 조건 중 하나 없애고 싶을 때, 조건 중 하나를 무조건 WHERE로 올려야 하는데, WHERE 1=1이 있으면 그러지 않아도 됨
FROM 어느 테이블에서 가져올지 지정하는 것
LIMIT
데이터를 몇 개까지 둘지 제한하는 것
비교 연산자와 논리 연산자
등호 연산자
부등호 연산자
SELECT product_id, category
FROM products
WHERE 1=1
AND category <> '키즈'
category가 '키즈'가 아닌 것
<> 대신 != 도 가능하다
논리 연산자 : AND
SELECT name, price
FROM products
WHERE 1=1
AND price < 10000
AND category = '주방용품'
논리 연산자 : OR
SELECT name, price
FROM products
WHERE 1=1
AND price < 12000
AND (category = '주방용품'
OR name = '손목보호대')
price가 12000보다 작으면서, category가 주방용품이거나 name이 손목보호대인 경우
괄호 안의 연산을 먼저 수행함
논리 연산자 : NOT
참 거짓을 뒤집는 데 사용함
SELECT *
FROM products
WHERE 1=1
AND NOT category = '키즈'
카테고리가 치즈인 경우를 뒤집었으므로 카테고리가 키즈가 아닌 경우만 필터링 하게 됨
논리 연산자 : IN
좌측 값이 우측 괄호 안에 포함될 때 참을 반환
# 논리 연산자 : IN
SELECT product_id, name
FROM products
WHERE 1=1
AND category IN ('스포츠', '디지털', '식품')
논리 연산자 : NOT IN
좌측 값이 우측 괄호 안에 포함되지 않는 행들만 반환
# 논리 연산자 : NOTIN
SELECT product_id, name
FROM products
WHERE 1=1
AND category NOT IN ('스포츠', '디지털', '식품')
논리 연산자 : LIKE
문자열의 패턴을 검색하는 데 사용
% = 모든 문자열을 나타냄
SELECT product_id, name
FROM product
WHERE 1=1
AND name LIKE "%보호%"
보호라는 문자열 앞 뒤로 무슨 문자가 오든지 보호라는 문자열을 포함하면 반환하라는 의미
SELECT product_id, name
FROM managers
WHERE 1=1
AND off LIKE "%일%"
%가 뒤쪽에만 붙은 경우 밥%
밥 뒤에는 아무거나 와도 상관없지만 앞에는 붙으면 안됨
_는 한개의 문자열
_그릇
그릇 앞에 하나의 문자열만 오는 경우만 반환! -> 사기그릇은 안됨
_를 여러 개 사용한다면 그 개수만큼 글자가 와야 한다는 의미임
SELECT *
FROM products
WHERE 1=1
AND name LIKE "_목%"
맨 앞에 한 글자 오고 그 다음에 목, 그 다음엔 아무거나 상관없음
SELECT *
FROM products
WHERE 1=1
AND name LIKE "어린이__%"
논리 연산자 : BETWEEN - 양쪽 끝 값을 포함
가격이 5000 이상 15000 이하인 행들만 필터링 하라
SELECT *
FROM orders
WHERE 1=1
AND purchase_date between
'20231001' and '20231003'
20231001~20231003 사이의 purchase_date 행들을 가져옴
논리 연산자 : IS NULL
테이블 내 특정 값이 비어있다는 것
# is null
SELECT *
FROM orders
WHERE 1=1
AND purchase_date IS NULL
NULL 값이 아닌 것을 반환하려면 IS NOT NULL을 사용
정렬과 집계
정렬과 집계 : ORDER BY
순서대로 정렬함
SELECT *
FROM products
WHERE 1=1
AND category in ('주방용품', '디지털')
ORDER BY price DESC
카테고리가 주방용품, 디지털인 것들 중 price가 높은 것부터 내림차순으로
문자 컬럼에도 가능!
한글은 가나다 순, 영어는 알파벳 순으로 정렬됨
여러 컬럼을 가지고 1차, 2차 정렬 가능
select price, name
from products_v2
where 1=1
order by price desc, name
price에 대해 1차 정렬, name에 대해 2차 정렬(price가 같은 값인 경우에)
price 내림차순, name 내림차순
같은 가격인 경우 가나다 반대 순
1은 최종 결과의 첫번째 컬럼, 2는 최종 결과의 두 번째 컬럼
select price, name
from products_v2
where 1=1
order by 1 desc, 2
price, name 순으로 선택했으므로 이 순서대로 정렬할 수 있음
price, name 순으로 정렬한다는 말임
SELECT product_id, category, name, price
FROM products_v2
ORDER BY 3 DESC
3번째 컬럼인 이름 순으로 내림차순으로 정렬됨
내림차순이니 가나다 역순!
SELECT product_id, category, name, price
FROM products_v2
ORDER BY 4 ASC, category DESC
price 순으로 오름차순. 기본이 ASC이니 삭제해도 됨
그 다음에는 category 컬럼을 내림차순으로 정렬함
SELECT product_id, category, name, price
FROM products_v2
ORDER BY 4
LIMIT 3
# price 순으로 정렬하고 3개까지만 자르기 때문에
# 가격이 저렴한 순으로 상위 3개만 노출됨
정렬과 집계 : 전체 집
집계함수 : 여러 행으로부터 하나의 결과값을 반환하는 함수
집계함수 : 평균, 합계, 최대, 최소 ㄷ,ㅇ
열에 대한 연산 수행
SELECT sum(price) as sum_price, avg(price) as avg_price
FROM products_v2
WHERE 1=1
price 컬럼에 대해 sum 집계함수 수행
as 붙이고 컬럼명 입력 시 컬럼 값에 대한 새로운 컬럼명이 생성됨
avg : 컬럼값 전체의 평균을 구함
SELECT name as name_v2, 'programmers' as new_col
FROM products_v2
LIMIT 3
COUNT : 조건에 맞는 행수 반환
SELECT count(1) as cnt
FROM products_v2
WHERE 1=1
count 안에 1이 들어간 것은 NULL과 관계 없이 행 수를 세겠다는 것임!
어떤 컬럼 값에 NULL이 있어도 count(1)은 어떤 특정 컬럼을 지정한 것이 아니라 상관없음
count(*)도 동일한 결과임
count(price) => NULL 값 제외하고 다른 행의 개수를 셈
컬럼 값의 중복 여부는 고려하지 않음
특정 컬럼 지정 후 그 앞에 distincnt를 적어주면 중복을 제거한 개수를 반환함
SELECT count(distinct price) as unique_price_cnt
필터링 적용된 후에 집계를 함
WHERE 절에 해당하는 행을 뽑은 다음 집계함
SELECT count(1) as some_cnt
FROM products_v2
WHERE 1=1
AND category like '%용품'
# 용품으로 끝나는 행을 필터링한 후 개수를 셈
SELECT category, count(1) as sales_cnt
FROM products_v3
WHERE 1=1
AND sale_yn = 'yes'
GROUP BY 1
ORDER BY 2 DESC, 1
# 카테고리 별 상품 수를 세는 쿼리
# GROUP BY : SELECT 문에 그룹으로 묶을 기준이 되는 category를 먼저 써주고 숫자를 셀 거기 때문에 count 작성
sale_yn=yes인 경우만 카운트함
group by 1 ->select한 첫 번째 컬럼을 의미함. 여기서는 category
category로 그룹화 진행 후 count 적용
반환된 결과 값이 순서를 order by가 적용
sales_cnt를 내림차순으로 정렬하고, count가 같다면 category 이름으로 오름차순 정렬
count가 동일하므로 카테고리에 대해 가나다순으로 진행됨
집계 함수는 두 개 이상의 컬럼에 대해서도 그룹화 가능
select category, sale_yn, avg(price) as avg_price
from products_v3
group by 1, 2
category, sale_yn으로 그룹화하고, 각 그룹별 평균 가격을 구하라는 select문
ORDER BY 3 DESC 추가하면 avg_price가 높은 순서대로 정렬됨
WHERE은 그룹화 하기 전에 필터링
HAVING은 그룹화 이후에 필터링
HAVING
select category, sale_yn, avg(price) as avg_price
from products_v3
where 1=1
group by 1, 2
having avg_price > 3000
# category, sale_yn에 대해 그룹화를 하고, 그 결과에 대해 평균 가격(avg_price)이 3000 초과인 경우만 반환
select category, sale_yn, avg(price) as avg_price
from products_v3
where 1=1
group by 1, 2
# 집계 전 필터링
# 3천원 넘는 제품들의 평균 가격을 구함
이게 가격이 좀 더 높음
그룹화 하기 전 필터링하기 때문
기초 SQL 함수
CONCAT : 여러 컬럼의 문자열 값들을 하나의 컬럼으로 합침
SELECT CONCAT(category, '-', name) as comb_name
FROM products
WHERE 1=1
LIMIT 3
category와 name을 -로 이어준다
products 테이블에서
상위 3개만
'-' 대신 ' '으로 지정하면 공백으로 이어줌
SELECT CONCAT(name, '의 가격은', price, '입니다.') as comb_name
FROM products
WHERE 1=1
LIMIT 3
SUBSTRING : 문자열에서 일부분만 추출
문자열을 잘라서 부분만을 변환하는 함수
3개가 인풋
추출을 원하는 컬럼명, 시작 위치, 추출 원하는 길이
name이라는 컬럼에 첫 번째 값부터 2번째 길이만큼 추출하는 것
SUBSTR도 가능
LEFT, RIGHT도 가능한데 왼쪽, 오른쪽으로부터 추출하는 것임
SELECT SUBSTRING(name, 2, 3) as sub_string
FROM products
WHERE 1=1
SELECT LEFT(name, 3) as sub_string
FROM products
맨 왼쪽부터 3개의 문자열 추출
RIGHT로 바꾸면 오른쪽 끝부터 3개의 문자열 추출
UPPER, LOWER 함수가 있음
SELECT UPPER('John') as up, LOWER('JOHN') as low
UPPER는 대문자로, LOWER는 소문자로
CHAR_LENGTH : 문자열의 길이 반환
ROUND : 반올림을 하는 함수
SELECT ROUND(avg(price)) as avg_price
FROM products_v2
WHERE 1=1
소수점 몇번째 자리까지 남길지 두번째 인풋으로 지정 가능
SELECT ROUND(avg(price), 1) as avg_price # 소수점 이하 한자리까지만 남김
FROM products_v2
CEIL : 소수점 올림 함수
SELECT CEIL(avg(price)) as avg_price
FROM products_v2
FLOOR : 소수점 내림 함수
SELECT FLOOR(avg(price)) as avg_price
FROM products_v2
TRUNCATE : 특정 자릿수 이하를 잘라서 버리는 함수
SELECT TRUNCATE(avg(price),2) as avg_price
FROM products_v2
소수점 셋째자리부터 다 버림
ABS : 절댓값 함수
MOD : 나머지를 구하는 함수-첫번째가 인자, 분모
나누어지는 수, 나누는 수 순서대로 입력함
POW : X의 Y승
GREATEST : 입력 인자들 중 최대값 반환
LEAST : 최소값 반환
COALESCE : NULL 값을 채우기 위해 사용됨
null 값을 특정 값으로 채움
SELECT COALESCE (purchase_date, product_name) as purchase_date
FROM orders
DDL, DML
1. DDL(Data Definition Launguage) : 데이터베이스 구조를 정의하고 관리
- CREATE : 테이블/뷰/인덱스 생성
- ALTER : 테이블/뷰/인덱스 구조 변경
- DROP : 테이블/뷰/인덱스 삭제
2. DML(Data Manipulation Lauguage) : 데이터를 쿼리하거나 조작
- SELECT : 데이터 가져오기
- INSERT : 데이터 삽입
- UPDATE : 데이터 수정
- DELETE : 데이터 삭제
CREATE
CREATE TABLE IF NOT EXISTS `products` ( # 테이블이 없으면 products라는 테이블을 만들겠다.
`product_id` int unsigned NOT NULL, # 컬럼이름, 타입, 널 값 여부 순으로 입력, unsigned: 양수만
`category` varchar(40) NOT NULL, # category라는 가변 길이의 문자열 저장
`name` varchar(50) NOT NULL, # 문자열 길이에 따라 저장 공간 다르게 쓰는 것 불가
`price` int unsigned NOT NULL, # 정수형 타입으로 양수안됨
PRIMARY KEY (`product_id`) # PRIMARY KEY는 테이블 내 모든 행에 적용되는 고유한 ID
) DEFAULT CHARSET=utf8; # 테이블의 기본 문자 세트. 한글이므로 utf-8
# 프라이머리 키를 통해 테이블 내에서 정확하게 몇 행인지를 식별할 수 있음
# 각 행에 대한 주민번호임
char : 저장공간보다 문자열이 짧아도 공백으로 채움
varchar : 문자열의 길이에 맞게 저장공간을 할당
컬럼이 기본키가 되려면 행마다 다른 값이 되어야 함
varchar(6)인데 어린이칫솔거치대가 글자가 많아서 빌드가 안됨
ALTER
ALTER TABLE products drop column price;
# products 테이블에서 price 컬럼 지우기
ALTER TABLE products ADD price int NULL
# price 컬럼 추가하기, int 타입이지만 널값도 가능하게 함
DROP
RDBMS 내 객체 삭제
DROP TABLE products;
products 테이블 삭제
INSERT
CREATE로 테이블 만들고 INSERT INTO로 데이터 삽입!
UPDATE
테이블에 삽입된 레코드 수정
UPDATE prodcuts
SET price = 20000
WHERE price = 15000;
price가 15000인걸 찾아서 20000으로 변경
UPDATE 테이블 SET 컬럼
DELETE
DELETE FROM products
WHERE price = 15000;
DELETE FROM 테이블
- 조건이 여러 개 일때, WHERE 1=1 써놓고 이 아래에 AND를 사용하여 조건 정렬
- 중복 없는 행을 SELECT 할 때, SELECT 써놓고 컬럼명 앞에 DISTINCT 쓰기
- 단위 바꿀 때는 수를 곱하기
- 문제 설명
- 다음은 어느 대학교의 학생 정보를 담은 PCSQL_STUDENTS 테이블입니다.
PCSQL_STUDENTS 테이블은 아래와 같은 구조로 되어있으며, ID, NAME, DEPARTMENT_ID, TUITION, TOEIC, GRADUATED는 각각 학생의 학번, 성명, 소속 학부의 ID, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.COLUMN NAMETYPENULLABLEID INTEGER FALSE NAME VARCHAR(255) FALSE DEPARTMENT_ID INTEGER FALSE TUITION INTEGER FALSE TOEIC INTEGER TRUE GRADUATED BOOLEAN FALSE
문제PCSQL_STUDENTS 테이블에는 학생의 학번, 이름, 소속 학부, 등록금을 조회해주세요. 이때 등록금은 1원 단위로 변경해 나타내고 컬럼 이름은 TUITION을 사용해주세요. 결과는 학번 순으로 정렬되어야 합니다.
예시예를 들어 PCSQL_STUDENTS 테이블이 다음과 같다면IDNAMEDEPARTMENT_IDTUITIONTOEICGRADUATED20400003 박서준 1 300 960 FALSE 20400001 이서연 2 500 740 FALSE 20410001 김서윤 2 500 200 FALSE 20410002 이서연 2 500 FALSE 20400002 정도윤 3 480 900 FALSE 20410003 조하윤 3 480 770 FALSE 20400005 강시우 3 480 FALSE 20400004 박예준 1 300 800 TRUE 20410004 김서현 1 300 TRUE 20410005 최지우 3 480 300 TRUE 20400001 이서연 2 5000000 20400002 정도윤 3 4800000 20400003 박서준 1 3000000 20400004 박예준 1 3000000 20400005 강시우 3 4800000 20410001 김서윤 2 5000000 20410002 이서연 2 5000000 20410003 조하윤 3 4800000 20410004 김서현 1 3000000 20410005 최지우 3 4800000
SELECT ID, NAME, DEPARTMENT_ID, TUITION*10000 as TUITION
FROM PCSQL_STUDENTS
ORDER BY ID
문제 설명
다음은 어느 대학교의 학생 정보를 담은 PCSQL_STUDENTS 테이블입니다.
PCSQL_STUDENTS 테이블은 아래와 같은 구조로 되어있으며, ID, NAME, DEPARTMENT_ID, TUITION, TOEIC, GRADUATED는 각각 학생의 학번, 성명, 소속 학부의 ID, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.
ID | INTEGER | FALSE |
NAME | VARCHAR(255) | FALSE |
DEPARTMENT_ID | INTEGER | FALSE |
TUITION | INTEGER | FALSE |
TOEIC | INTEGER | TRUE |
GRADUATED | BOOLEAN | FALSE |
문제
장학금 신청 요건을 만족한 학생들에게 연락을 하려고 합니다. PCSQL_STUDENTS 테이블에서 연락받을 학생의 학번과 이름을 학번 순으로 출력하는 SQL 문을 작성해 주세요.
장학금 신청 조건:
- 졸업하지 않았어야 한다.
- 토익 점수가 500 이상이어야 한다.
- 단, 영문학부는 토익 자격증 점수가 800점 이상이어야 한다.
- 영문 학부의 학부 ID는 3이다.
예시
예를 들어 PCSQL\_STUDENTS 테이블이 다음과 같다면
IDNAMEDEPARTMENT_IDTUITIONTOEICGRADUATED20400003 | 박서준 | 1 | 300 | 960 | FALSE |
20400001 | 이서연 | 2 | 500 | 740 | FALSE |
20410001 | 김서윤 | 2 | 500 | 200 | FALSE |
20410002 | 이서연 | 2 | 500 | FALSE | |
20400002 | 정도윤 | 3 | 480 | 900 | FALSE |
20410003 | 조하윤 | 3 | 480 | 770 | FALSE |
20400005 | 강시우 | 3 | 480 | FALSE | |
20400004 | 박예준 | 1 | 300 | 800 | TRUE |
20410004 | 김서현 | 1 | 300 | TRUE | |
20410005 | 최지우 | 3 | 480 | 300 | TRUE |
SQL을 실행하면 다음과 같이 출력되어야 합니다.
IDNAME20400001 | 이서연 |
20400002 | 정도윤 |
20400003 | 박서준 |
SELECT ID, NAME
FROM PCSQL_STUDENTS
WHERE 1=1
AND GRADUATED = FALSE
AND (DEPARTMENT_ID <>3 AND TOEIC >=500)
OR (DEPARTMENT_ID = 3 AND TOEIC > 800)
문제 설명
다음은 어느 대학교의 학생 정보를 담은 PCSQL_STUDENTS 테이블입니다.
PCSQL_STUDENTS 테이블은 아래와 같은 구조로 되어있으며, ID, NAME, DEPARTMENT_ID, TUITION, TOEIC, GRADUATED는 각각 학생의 학번, 성명, 소속 학부의 ID, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.
ID | INTEGER | FALSE |
NAME | VARCHAR(255) | FALSE |
DEPARTMENT_ID | INTEGER | FALSE |
TUITION | INTEGER | FALSE |
TOEIC | INTEGER | TRUE |
GRADUATED | BOOLEAN | FALSE |
문제
PCSQL_STUDENTS 테이블에서 이름이 "김"으로 시작하는 학생의 학번, 성명을 학번 순으로 조회해 주세요.
예시
예를 들어 PCSQL_STUDENTS 테이블이 다음과 같다면
IDNAMEDEPARTMENT_IDTUITIONTOEICGRADUATED20400003 | 박서준 | 1 | 300 | 960 | FALSE |
20400001 | 이서연 | 2 | 500 | 740 | FALSE |
20410001 | 김서윤 | 2 | 500 | 200 | FALSE |
20410002 | 이서연 | 2 | 500 | FALSE | |
20400002 | 정도윤 | 3 | 480 | 900 | FALSE |
20410003 | 조하윤 | 3 | 480 | 770 | FALSE |
20400005 | 강시우 | 3 | 480 | FALSE | |
20400004 | 박예준 | 1 | 300 | 800 | TRUE |
20410004 | 김서현 | 1 | 300 | TRUE | |
20410005 | 최지우 | 3 | 480 | 300 | TRUE |
SQL을 실행하면 다음과 같이 출력되어야 합니다.
IDNAME20410001 | 김서윤 |
20410004 | 김서현 |
SELECT ID, NAME
FROM PCSQL_STUDENTS
WHERE 1=1
AND NAME LIKE "김%"
ORDER BY ID
문제 설명
다음은 어느 대학교의 학생 정보를 담은 PCSQL_STUDENTS 테이블입니다.
PCSQL_STUDENTS 테이블은 아래와 같은 구조로 되어있으며, ID, NAME, DEPARTMENT_ID, TUITION, TOEIC, GRADUATED는 각각 학생의 학번, 성명, 소속 학부의 ID, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.
ID | INTEGER | FALSE |
NAME | VARCHAR(255) | FALSE |
DEPARTMENT_ID | INTEGER | FALSE |
TUITION | INTEGER | FALSE |
TOEIC | INTEGER | TRUE |
GRADUATED | BOOLEAN | FALSE |
문제
PCSQL_STUDENTS 테이블에서 졸업하지 않은 학생과 졸업한 학생의 수를 순서대로 조회해주세요. 이때 학생 수를 나타내는 컬럼의 이름은 NUM으로 지정해야합니다.
예시
예를 들어 PCSQL_STUDENTS 테이블이 다음과 같다면
IDNAMEDEPARTMENT_IDTUITIONTOEICGRADUATED20400003 | 박서준 | 1 | 300 | 960 | FALSE |
20400001 | 이서연 | 2 | 500 | 740 | FALSE |
20410001 | 김서윤 | 2 | 500 | 200 | FALSE |
20410002 | 이서연 | 2 | 500 | FALSE | |
20400002 | 정도윤 | 3 | 480 | 900 | FALSE |
20410003 | 조하윤 | 3 | 480 | 770 | FALSE |
20400005 | 강시우 | 3 | 480 | FALSE | |
20400004 | 박예준 | 1 | 300 | 800 | TRUE |
20410004 | 김서현 | 1 | 300 | TRUE | |
20410005 | 최지우 | 3 | 480 | 300 | TRUE |
SQL을 실행하면 다음과 같이 출력되어야 합니다.
GRADUATEDNUMFALSE | 7 |
TRUE | 3 |
SELECT GRADUATED, COUNT(GRADUATED) as NUM
FROM PCSQL_STUDENTS
WHERE 1=1
GROUP BY GRADUATED
- GROUP BY - 학부별 토익 점수 확인하기
다음은 어느 대학교의 학생 정보를 담은 PCSQL_STUDENTS 테이블입니다.
PCSQL_STUDENTS 테이블은 아래와 같은 구조로 되어있으며, ID, NAME, DEPARTMENT_ID, TUITION, TOEIC, GRADUATED는 각각 학생의 학번, 성명, 소속 학부의 ID, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.
ID | INTEGER | FALSE |
NAME | VARCHAR(255) | FALSE |
DEPARTMENT_ID | INTEGER | FALSE |
TUITION | INTEGER | FALSE |
TOEIC | INTEGER | TRUE |
GRADUATED | BOOLEAN | FALSE |
문제
PCSQL_STUDENTS 테이블에서 학부 ID 별 최저 토익 점수, 최고 토익 점수, 토익 점수의 합을 조회해주세요. 이때 각 컬럼의 이름은 DEPARTMENT_ID, SCORE1, SCORE2, SCORE3으로 설정하고 ID가 낮은 학부를 먼저 조회해주세요.
예시
예를 들어 PCSQL_STUDENTS 테이블이 다음과 같다면
IDNAMEDEPARTMENT_IDTUITIONTOEICGRADUATED20400003 | 박서준 | 1 | 300 | 960 | FALSE |
20400001 | 이서연 | 2 | 500 | 740 | FALSE |
20410001 | 김서윤 | 2 | 500 | 200 | FALSE |
20410002 | 이서연 | 2 | 500 | FALSE | |
20400002 | 정도윤 | 3 | 480 | 900 | FALSE |
20410003 | 조하윤 | 3 | 480 | 770 | FALSE |
20400005 | 강시우 | 3 | 480 | FALSE | |
20400004 | 박예준 | 1 | 300 | 800 | TRUE |
20410004 | 김서현 | 1 | 300 | TRUE | |
20410005 | 최지우 | 3 | 480 | 300 | TRUE |
SQL을 실행하면 다음과 같이 출력되어야 합니다.
DEPARTMENT_IDSCORE1SCORE2SCORE31 | 800 | 960 | 1760 |
2 | 200 | 740 | 940 |
3 | 300 | 900 | 1970 |
SELECT DEPARTMENT_ID, MIN(TOEIC) as SCORE1, MAX(TOEIC) as SCORE2, SUM(TOEIC) as SCORE3
FROM PCSQL_STUDENTS
GROUP BY DEPARTMENT_ID
ORDER BY DEPARTMENT_ID
제 설명
다음은 어느 대학교의 학생 정보를 담은 PCSQL_STUDENTS 테이블입니다.
PCSQL_STUDENTS 테이블은 아래와 같은 구조로 되어있으며, ID, NAME, DEPARTMENT_ID, TUITION, TOEIC, GRADUATED는 각각 학생의 학번, 성명, 소속 학부의 ID, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.
ID | INTEGER | FALSE |
NAME | VARCHAR(255) | FALSE |
DEPARTMENT_ID | INTEGER | FALSE |
TUITION | INTEGER | FALSE |
TOEIC | INTEGER | TRUE |
GRADUATED | BOOLEAN | FALSE |
문제
PCSQL_STUDENTS 테이블에서 토익 점수의 평균이 500 이상인 학부의 ID를 조회해주세요. 토익 점수가 없는 경우는 계산에 포함하지 않습니다. 이때 ID가 낮은 학부를 먼저 조회해주세요.
예시
예를 들어 PCSQL_STUDENTS 테이블이 다음과 같다면
IDNAMEDEPARTMENT_IDTUITIONTOEICGRADUATED20400003 | 박서준 | 1 | 300 | 960 | FALSE |
20400001 | 이서연 | 2 | 500 | 740 | FALSE |
20410001 | 김서윤 | 2 | 500 | 200 | FALSE |
20410002 | 이서연 | 2 | 500 | FALSE | |
20400002 | 정도윤 | 3 | 480 | 900 | FALSE |
20410003 | 조하윤 | 3 | 480 | 770 | FALSE |
20400005 | 강시우 | 3 | 480 | FALSE | |
20400004 | 박예준 | 1 | 300 | 800 | TRUE |
20410004 | 김서현 | 1 | 300 | TRUE | |
20410005 | 최지우 | 3 | 480 | 300 | TRUE |
- 1번 학부에 소속된 학생들의 토익 점수는 960, 800점입니다. 평균 점수가 880점이므로 1번 학부를 결과에 포함합니다.
- 2번 학부에 소속된 학생들의 토익 점수는 740, 200점입니다. 평균 점수가 470점이므로 2번 학부는 결과에 포함하지 않습니다.
- 3번 학부에 소속된 학생들의 토익 점수는 900, 770, 300점입니다. 평균 점수가 656.667 점이므로 3번 학부를 결과에 포함합니다.
따라서 SQL을 실행하면 다음과 같이 출력되어야 합니다.
DEPARTMENT_ID1 |
3 |
SELECT DEPARTMENT_ID
FROM PCSQL_STUDENTS
WHERE 1=1
GROUP BY DEPARTMENT_ID
HAVING AVG(TOEIC) >= 500
ORDER BY DEPARTMENT_ID
문제
PCSQL_STUDENTS 테이블서 동명이인이 있는 이름을 조회해주세요. 이때 중복은 제외하고, 이름을 사전순으로 나열해주세요.
예시
예를 들어 PCSQL_STUDENTS 테이블이 다음과 같다면
IDNAMEDEPARTMENT_IDTUITIONTOEICGRADUATED
20400003 | 박서준 | 1 | 300 | 960 | FALSE |
20400001 | 이서연 | 2 | 500 | 740 | FALSE |
20410001 | 김서윤 | 2 | 500 | 200 | FALSE |
20410002 | 이서연 | 2 | 500 | FALSE | |
20400002 | 정도윤 | 3 | 480 | 900 | FALSE |
20410003 | 조하윤 | 3 | 480 | 770 | FALSE |
20400005 | 박서준 | 3 | 480 | FALSE | |
20400004 | 박예준 | 1 | 300 | 800 | TRUE |
20410004 | 김서현 | 1 | 300 | TRUE | |
20410005 | 최지우 | 3 | 480 | 300 | TRUE |
SQL을 실행하면 다음과 같이 출력되어야 합니다.
NAME
박서준 |
이서연 |
SELECT NAME
FROM PCSQL_STUDENTS
WHERE 1=1
GROUP BY NAME
HAVING COUNT(*) > 1
ORDER BY NAME