SQL(structured query language): 데이터베이스 조작에 필요한 언어
일반적인 용도로는
database라는걸 만들고 그 안에 여러개의 table을 보관한다.
database는 일종의 '폴더'이고, tabled은 '파일'이다.
table 안에 원하는 데이터 엑셀처럼 작성하면 된다.
1-1.
터미널 창에
cd /usr/local/mysql/bin
./mysql -uroot -p
명령어를 입력하고, MySQL 서버를 활성화 시키자.
1-2.
Database 생성하기!
1-3.
table 생성하기!
1-4. 데이터 타입의 종류
2-1. 데이터를 출력하려면 SQL언어를 이용해서 코드 작성
파일 내에 한글이 있으면, 인코딩에 euc-kr을 입력해야함
SELECT 컬럼명 FROM 테이블명 WHERE 조건식
SELECT * FROM product WHERE 카테고리 = '가구'
SELECT * FROM product WHERE 가격 BETWEEN 5000 AND 8000
SELECT * FROM product
WHERE 카테고리 = '가구' AND 가격 = 5000;
SELECT * FROM product
WHERE NOT 카테고리 = '가구';
SELECT * FROM product
WHERE (카테고리 = '가구' OR 카테고리 = '옷') AND 가격 = 5000;
SELECT * FROM product
WHERE 카테고리 IN ('신발', '가전, '식품');
SELECT FROM 뒤에 WHERE 조건식을 붙여서 필터링할 수 있다.
조건식란엔 > , < , = , != , >= , <= 전부 이용 가능하다.
조건식 여러 개가 필요하면 AND, OR 이런 걸로 이어붙일 수 있다.
괄호로 AND, OR 사용한 부분을 묶을 수도 있다.
OR 조건식 여러 개 필요하면 IN() 사용해도 될 때가 있다.
SELECT * FROM product
WHERE 상품명 LIKE '%소파%' ;
CHAR(6) 데이터타입의 경우 총 6자를 저장할 수 있는데
4자만 입력해도 나머지 뒷부분 2자를 공백으로 꽉 채워줍니다.
예를 들어서 '가죽소파'를 저장해도 '가죽소파_ _' 이렇게 저장됩니다.
그래서 CHAR 컬럼은 % 써서 검색시 의도와 다르게 동작할 수 있습니다.
'%소파' 이렇게 검색해도 '가죽소파_ _' 이건 못찾음
SELECT * FROM newtable WHERE 상품명 LIKE '%소파%' OR 상품명 LIKE '%chair%' ;
SELECT * FROM newtable WHERE 상품명 LIKE '%소파%' AND NOT 상품명 LIKE '%나무%'
SELECT MAX(사용금액) FROM card // 최댓값
SELECT MIN(사용금액) FROM card // 최솟값
SELECT MAX(사용금액), MIN(사용금액) FROM card
SELECT AVG(연체횟수) FROM card // 평균값
SELECT SUM(사용금액) FROM card // 전체합
SELECT COUNT(사용금액) FROM card
SELECT MAX(사용금액) AS 최대사용금액 FROM card
SELECT DISTINCT 연체횟수 FROM card
SELECT * FROM card ORDER BY 사용금액 DESC LIMIT 1;
Q3. 연체횟수가 1회 이하인 사람은 몇명일까요?
님이 직접 하나하나 세지 말고 컴퓨터보고 출력해달라고 해봅시다.
SELECT COUNT(연체횟수) FROM card
WHERE 연체횟수 <= 1;
SELECT CONCAT(고객명, ' is ', 사용금액) FROM card
컬럼명, 컬럼명만 해도 붙여줌
CONCAT() 안에 여러 문자들을 집어넣을 수 있다.
컬럼이름말고 직접 문자 입력해도 합쳐준다.
숫자 입력해도 문자처럼 합쳐준다.
SELECT TRIM(컬럼명) FROM 어쩌구 // 문자 데이터의 좌우 공백 제거
SELECT REPLACE(컬럼명, ' ', '') FROM 테이블명 // 응용
SELECT REPLACE (고객등급, '패', '훼') FROM card
// 고객등급 컬럼에 '패' 라는 글자를 '훼' 로 변경
SELECT REPLACE('서울에사는 서울맨', '서울', '경기')
// REPLACE(바꿀문자, 이걸찾아서, 이걸로바꾸셈)
SELECT SUBSTR('abcdef', 3, 2)
// SUBSTR(문자, 몇번째부터, 몇자)
SELECT INSERT('test@naver.com', 1, 4, 'hello')
// INSERT(바꿀문자, 몇번째부터, 몇자를, 이걸로바꾸셈)
SELECT GREATEST();
SELECT LEAST();
SELECT GREATEST(결제횟수, 연체횟수) FROM card // 예시
SELECT GREATEST(3, 12, 34, 8, 25);
// 하나의 행이나 숫자배열 안에서 최대, 최소를 뽑아줌
SELECT FLOOR(10.1); // 소수 부분 내림해서 정수로 변환
SELECT FLOOR(10.9);
SELECT CEIL(10.1); // 소수 부분 올림해서 정수로 변환
SELECT CEIL(10.9);
SELECT ROUND(10.777, 2); // 반올림
SELECT TRUNCATE(10.777, 2); // 반내림
SELECT POWER(4, 2); // 거듭제곱
SELECT ABS(-100); // 절댓값 출력
※ 쿼리문은 sql 한 문장을 뜻함
사용금액의 평균 이상의 값들만 출력하고 싶을 때
SELECT * FROM card
WHERE 사용금액 > (SELECT AVG(사용금액) FROM card);
SELECT 사용금액 FROM card
WHERE 고객명 IN ('Pristine', 'George', 'Amy')
SELECT 사용금액 FROM card
WHERE 고객명 IN (SELECT 이름 FROM blacklist)
Q1.
"고객등급이 패밀리인 사람들의 평균 연체횟수"보다 연체횟수가 높은 사람은 몇명일까요?
SELECT COUNT(*) FROM card
WHERE 연체횟수 >
(SELECT AVG(연체횟수) FROM card WHERE 고객등급 = '패밀리');
// 내가 짠 코드, 순차적으로 필터링함
SELECT 고객명, 사용금액, 사용금액 - (SELECT AVG(사용금액) FROM card) FROM card;
// 내가 짠 코드
SELECT 고객명, 사용금액, 사용금액 - (SELECT AVG(사용금액) FROM card) AS DIFF FROM card;
// 선생님이 짠 코드
https://bcdragonfly.tistory.com/8
나의 해결법
SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); // 추가
SELECT * FROM card GROUP BY 고객등급
10-2.
SELECT * FROM card
GROUP BY 고객등급;
SELECT 고객등급 FROM card
GROUP BY 고객등급;
card 테이블 안에 모든 컴럼의 '고객등급' 컴럼을 그룹화
card 테이블 안에 모든 '고객등급' 컬럼의 '고객등급' 컴럼을 그룹화
// 응용
SELECT 고객등급, COUNT(고객명) FROM card
GROUP BY 고객등급;
SELECT 고객등급, AVG(사용금액) FROM card
GROUP BY 고객등급
SELECT 고객등급, COUNT(고객명) FROM card
GROUP BY 고객등급 HAVING 고객등급 = 'vip';
HAVING vs WHERE
HAVING은 용도가 WHERE과 비슷하다. 둘 다 조건식 입력하는 문법
SELECT 고객등급, COUNT(고객명) FROM card WHERE 연체횟수 = 0
GROUP BY 고객등급 HAVING 고객등급 = 'vip';
Q1. 위 사진처럼 card 테이블에서 연체횟수마다 몇명이 있는지 출력해봅시다.
SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
SELECT 고객명, 연체횟수 ,COUNT(연체횟수) AS 연체카운트 FROM card
GROUP BY 연체횟수
ORDER BY 연체횟수;
Q2. Q1에서 출력한 결과가 너무 길어서 몇명이냐면 컬럼의 값이 1명인 행은 안보이게 필터링해봅시다.
SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
SELECT 고객명, 연체횟수 ,COUNT(연체횟수) AS 연체카운트 FROM card
GROUP BY 연체횟수 HAVING NOT 연체카운트 = 1
ORDER BY 연체횟수;
SELECT IF(1 + 2 = 3, '맞음', '틀림');
SELECT 고객명, 사용금액, IF(사용금액>200000, "우수", "거지") FROM card;
출력
CASE
WHEN 조건식1 THEN 남길값1
WHEN 조건식2 THEN 남길값2
WHEN 조건식3 THEN 남길값3
END
Q.
사용금액이 20만원 이상이면 '우수'
사용금액이 10~20만원이면 '준수'
사용금액이 10만원 미만이면 '그지'
SELECT 고객명, 사용금액,
CASE
WHEN 사용금액 >= 200000 THEN '우수'
WHEN 사용금액 >= 100000 AND 사용금액 < 200000 THEN '준수'
WHEN 사용금액 < 100000 THEN '그지'
END
FROM card;
// 이렇게 줄일 수 있음
SELECT 고객명, 사용금액,
CASE
WHEN 사용금액 >= 200000 THEN '우수'
WHEN 사용금액 >= 100000 THEN '준수'
ELSE '그지'
END
FROM card;
Q.
등급이 vip인 사람들은 3점, 로열이면 2점, 패밀리면 1점으로 계산해서 모든 고객의 점수를 다 더하면 몇점일까요?
SELECT SUM(3) FROM card // 모든 행에 3을 더해줌
SELECT SUM(
CASE
WHEN 고객등급 = 'vip' THEN 3
WHEN 고객등급 = '로열' THEN 2
ELSE 1
END
) AS 등급별_합계
FROM card;
Q1.
card 테이블에서 장부를 조작하려고 합니다.
사용금액 30만원 이상은 50% 증액, 30만원 미만은 10% 증액해서
사용금액의 총 합계를 출력해봅시다. 답은 5147550로 나오면 정답입니다.
// 내가 짠 코드
SELECT 고객명, SUM(
CASE
WHEN 사용금액 >= 300000 THEN 사용금액 * 1.5
ELSE 사용금액 * 1.1
END
) AS 합계 , 고객등급 FROM card;
// 선생님이 짠 코드
SELECT SUM(
IF( 사용금액 >= 300000, 사용금액 * 1.5, 사용금액 * 1.1 )
) FROM mart.card
Q2.
고객등급을 재설정하려고 합니다.
사용금액이 30만원 이상은 'vip'
20만원 이상 30만원 미만은 '로열'
그 외엔 '패밀리'로 다시 설정하려고 합니다.
고객등급이 변동될 이름들만 출력해봅시다.
1.
SELECT 고객명, 사용금액, 고객등급,
CASE
WHEN 사용금액 >= 300000 THEN 'vip'
WHEN 사용금액 >= 200000 THEN '로열'
ELSE '패밀리'
END
FROM card
2.
SELECT 고객명, 사용금액, 고객등급
FROM card
WHERE 고객등급 != CASE
WHEN 사용금액 >= 300000 THEN 'vip'
WHEN 사용금액 >= 200000 THEN '로열'
ELSE '패밀리'
END
// 순차적으로 코딩