본문 바로가기
카테고리 없음

데이터분석 > 2주차 > 파트 08 > 0823

by 나는야석사 2024. 8. 24.

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가 질의에 맞는 형태의 데이터를 돌려준다.

https://www.db-fiddle.com/

 

DB Fiddle - SQL Database Playground

 

www.db-fiddle.com

SQL을 웹사이트에서 사용할 수 있고 테이블 시각화 가능

 

- 데이터 조회

SQL Query에서 기본 뼈대가 되는 것은 3가지임

SELECT, FROM, WHERE

  • SELECT : 무엇을 가져올지 지정(테이블에서 원하는 컬럼을 가져오는 역할)
  • FROM : 어디에서 가져올지 지정
    • 테이블이 여러 개일 경우 어디서 가져올지도 지정
  • WHERE : 어떤 조건으로 가져올지 지정
    • WHERE 이하 조건에 일치하는 경우만 가져옴
    • 행을 선택하기 위한 목적

DB fiddle 사용한 결과

모든 컬럼 가져오고 싶을 시 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 NAMETYPENULLABLE
    ID 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_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을 실행하면 다음과 같이 출력되어야 합니다.IDNAMEDEPARTMENT_IDTUITION
    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, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.

COLUMN NAMETYPENULLABLE
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_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을 실행하면 다음과 같이 출력되어야 합니다.

IDNAME
20400001 이서연
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, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.

COLUMN NAMETYPENULLABLE
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_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을 실행하면 다음과 같이 출력되어야 합니다.

IDNAME
20410001 김서윤
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, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.

COLUMN NAMETYPENULLABLE
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_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을 실행하면 다음과 같이 출력되어야 합니다.

GRADUATEDNUM
FALSE 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, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.

COLUMN NAMETYPENULLABLE
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_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을 실행하면 다음과 같이 출력되어야 합니다.

DEPARTMENT_IDSCORE1SCORE2SCORE3
1 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, 등록금(단위: 만원), 토익 점수, 졸업 여부를 나타냅니다.

COLUMN NAMETYPENULLABLE
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_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
  • 1번 학부에 소속된 학생들의 토익 점수는 960, 800점입니다. 평균 점수가 880점이므로 1번 학부를 결과에 포함합니다.
  • 2번 학부에 소속된 학생들의 토익 점수는 740, 200점입니다. 평균 점수가 470점이므로 2번 학부는 결과에 포함하지 않습니다.
  • 3번 학부에 소속된 학생들의 토익 점수는 900, 770, 300점입니다. 평균 점수가 656.667 점이므로 3번 학부를 결과에 포함합니다.

따라서 SQL을 실행하면 다음과 같이 출력되어야 합니다.

DEPARTMENT_ID
1
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