어리바리 신입 개발자의 얼렁뚱땅 개발 기록 ✨
23.05.09 / SELECT, WHERE AND/OR , BTEWEEN, LIKE, CASE 본문
[데이터베이스 선택 가이드]
1. KEY -VALUE Database
- 데이터를 키 -밸류로 저장하는 데이터 베이스
- 실용성이 떨어지고, 서브DB로 사용
Redis : 특이하고 많이 사용
데이터를 하드디스크에 저장. redis는 RAM에 저장. RAM에 저장 > 속도 빠름
메인 DB를 RAM에 복사하고, 필요한 데이터를 RAM에서 꺼내서 사용
2. RDBMS
- 데이터를 표 형태로 저장하고 싶을 때, 관계형 데이터베이스를 사용한다.
- 어떻게 데이터를 저장할지 이름(속성)을 작성하고, 데이터를 저장.
- 다양한 분야에서 사용할 수 있어서 RANK에 상위권은 모두 RDBMS
- RDBMS는 데이터를 저장하고 싶으면, SQL을 사용한다.
- 하지만, RDBMS는 데이터의 중복을 싫어함 때문에 반드시 지켜야하는 것이 정규화.
- 데이터가 중복되면 다른 테이블로 옮긴다. (정규화)
- 단점 : 정규화 진행 -> 데이터를 조회하는 문법이 어려워지고, 복잡해짐
- 장점 : 기본적으로 트랜잭션(나중에 함)을 가지고 있어서, 돈 거래 서비스를 만드는데 유용함
- 데이터의 입출력 속도보다는 정확도가 중요한 서비스를 만들 때 선택한다.
3. Graph Database
- GraphQL이라는 언어를 사용해야함
SNS의 친구 관계도, 전염병 지도,항공기 노선도
4. Document Database
- 관계형 데이터베이스보다 자유롭다.
- 폴더를 하나 만들고, 폴더 안에 Document라는 파일을 만들어서 데이터를 JSON형태로 저장한다.
(이름 : LEE 나이 : 20)
- 어떤 데이터를 저장할지 속성을 미리 지정할 필요가 없다.
예) 기존 구조 : 이름 나이 / 나중에 이람 나이 주소로 구조가 변경되어도 에러가 발생하지 않음
=> 데이터의 중복 제거 없음 / 정규화 없음 / 대신 DB의 정확도가 떨어질 수 있음
5. Column-family Database
- 관계형DB와 같이 표 형식으로 데이터를 저장하면서 유연하게 사용 가능
- 똑같이 테이블을 만들고, ROW를 만드는데, 데이터의 삽입이 자유롭다.
- 행마다 컬럼이 달라도 무관하다.
- 단, 데이터의 입출력 하려면, SQL을 사용하지 않고, 자기들이 만든 언어를 사용해야 한다.
- 정규화 없음 -> 데이터의 중복 허용
- 장점 : 데이터 입출력 쉬움, 분산 처리 용이 -> 많은 양의 데이터 입출력을 감당해야하는 경우 사용.
6. Search engin
- index를 보관하는 용도로 사용한다.
- 빠른 검색을 위한 목차의 역할
- 검색이 중요한 사이트를 만들 때 사용한다.
================================================================
SELECT
- 우리가 가장 많이 사용
연산자
- 숫자만 비교할 수 있다. x
- 문자 비교 가능하다.
SELECT
- 데이터베이스 내 테이블에서 원하는 데이터를 추출하는 명령어.
- SELECT를 잘 사용해야 데이터베이스를 잘 활용할 수 있다.
기본 구문
SELECT
조회하려는_열_이름
FROM
테이블_이름;
실행순서 = FROM -> SELECT
SELECT
회원_이름;
, 회원_주소
FROM
회원_테이블;
AS(alias)
- 원하는 이름을 붙일 수 있다.
- 생략은 가능하다.
- 열의 이름이 길어지는 경우, 별칭을 사용하면 좋다.
- 테이블 이름, 열 이름, WHERE절 사용 가능
- 길어서 보기 힘든 컬럼, 계산식이 복잡한 컬럼에 별칭 사용하면 좋다.
- 별칭 사용시, 작은 따옴표를 사용하는 것을 권장한다.
SELECT
c.Name AS '지역명'
, c.CountryCode
, c.Population
FROM
city AS c;
WHERE (AND / OR)
- 조건을 지정하는 WHERE절
- 조회하려는 결과에 특정한 조건을 줘서 원하는 데이터만 보고 싶을 때 사용한다.
- WHERE절 없이 조회하면, 모든 데이터를 죄회(테이블의 모든 행)
- 집계함수 함께 쓸 수 없음 WHERE SUM(g_price) > 3000000 불가능
기본 구문
SELECT
조회하려는_열_이름
FROM
테이블_이름;
WHERE
조건;
실행순서 = FROM -> WHERE -> SELECT
=============================================================
BETWEEN 작은수 AND 큰수 (WEHRE ~ AND ~) % 못 씀
- 범위를 지정한다.
집합, IN() (WHERE ~ OR ~) - 전체조회 % 못 씀
IN("KOR","USA","NLD")
전체조회
- OR를 사용하면 하나 씩 비교하기 때문에 성능이 저하된다.
- 코드가 간결해진다.
=============================================================
문자열의 내용을 검색하는 LIKE 연산자
- c.CountryCOde = LIKE'A%' 아님 / c.CountryCOde LIKE'A%' 가 맞음
- LIKE 키워드를 사용하여 문자를 필터링한다.
- % 기호는 그 자리에 어떤 값이 들어와서 상관 없다는 뜻
예 ) LIKE'한국%' -> 한국으로 시작하는 문자열을 찾는데 그 뒤에 뭐가 붙어도 상관 없음
한국인 한국사람 상관 없음 / LIKE'%한국' LIKE'한%국' LIKE'%한국%'도 가능
- 단일연산이기 때문에 c.CountryCOde LIKE'A%','B%' 이런식으로 못 씀
c.CountryCOde LIKE'A%' OR c.CountryCOde LIKE'B%'; 이런식으로 써야함
LIKE 심화
LIKE'한국_' (언더바 사용)
-> 5글자 탐색, 한국___ (언더바 3개)
EX) 아이돌 그룹 테이블
_ _ 핑크
블랙핑크 / 에이핑크
특정 문자 제외 탐색
LIKE'a%' ->a로 시작하는 + 아무 문자열
NOT LIKE'a%' ->a로 시작하지 않는 + 아무 문자열
=============================================================
중복을 제거하는 DISTINCT (SELECT DISTINCT)
- SQL은 기본적으로 중복을 제거하지 않는다. (조회 했을 때)
- 하나의 ROW를 기준으로 전체 컬럼을 비교한다.
예) 지역명 : SEOUL 인구 : 5,000 와 지역명 : SEOUL 인구 : 2,000를 다른 데이터로 봐서 중복 처리 X
=============================================================
조회되는 개수를 제한하는 LIMIT
LIMIT 숫자; (0~숫자)
LIMIT 0,100; (0~100)
=============================================================
데이터를 정렬하는 ORDER BY
- SELECT ~ FROM ~ WHERE 핵심 구문
- 부가적으로 출력 결과에 대해 중복 제거, 출력 개수 제한, 데이터 정렬 가능
- 기본 : 오름차순(기본 값)
- 내림차순 : DESC(Descending)
- 위치 : SELECT ~ FROM 다음에 ORDER BY 위치 (마지막에 위치)
정렬 랜덤 ORDER BY RAND()
- 아무 조건 없이 ORDER BY를 사용하면, PK 값를 오름차순 정렬 한다.
- RAND() 함수 사용하면 랜덤 출력 가능
정렬 기준 여러 개 가능
ORDER BY Name,District; => name을 먼저 오름차순 정렬 , 다음에 district를 오름차순 정렬
=============================================================
GROUP BY와 집계 함수
기본구문
SELECT
조회하려는_열_이름
FROM
테이블_이름;
WHERE
조건식
GROUP BY
그룹_지을_열_이름
HAVING
조건식
ORDER BY
정렬_열_이름
LIMIT 숫자;
GROUP BY
- 그룹으로 묶어주는 역할
- 속성 값이 같은 값끼리 그룹을 만들 수 있다.
- HAVING으로 그룹 출력 조건식을 작성할 수 있다.
full group by 에러 수정
1. root로 접속
2. SET GLOBAL sql_mode = (SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
3. HeidSQL 종료 후 다시 실행
GROUP BY는 방을 만들어주는 것
GROUP BY 사용했으면, 그룹 대상 컬럼을 SELECT에 조회해줘야 한다.
SELECT
c.CountryCode
, SUM(c.Population)
FROM
city AS c
GROUP BY c.CountryCode;
같은 c.CountryCode를 그룹으로 묶어줬기 때문에
SUM(c.Population) 했을 때
묶여 있는 c.CountryCode의 c.Population 모두 더해서 보여줌
만약 SUM(c.Population) 아니라 c.Population일 땐 그룹의 가장 첫 값 하나만 보여줌
집계 함수
종류
- 합계를 구하는 SUM()
- 평균을 구하는 AVG()
- 최솟갑, 최댇값 MIN(), MAX()
- 행의 개수를 세는 COUNT() : 테이블 모든 행의 개수를 센거나 특정 컬럼의 개수를 세고 싶을 때
SELECT
MAX(c.Population)
, MIN(c.Population)
FROM
city AS c;

SELECT
COUNT(*)
FROM
city AS c
WHERE
c.CountryCode = "KOR";
SELECT
COUNT(c.Name)
FROM
city AS c
WHERE
c.CountryCode = "KOR";
COUNT(*) / COUNT(c.Name) 두 개의 값이 같다.
이유는 c.Name에 null 값을 갖고 있는 행이 없기 때문
만약 null 값을 갖고 있는 행이 존재 할 때
COUNT(*) - NULL 포함
COUNT(c.Name) - NULL 제외
COUNT와 DISTINCT 함께 사용하기
SELECT
COUNT(DISTINCT c.CountryCode)
FROM
city AS c;
GROUP BY의 조건을 제한하는 HAVING
SELECT
c.CountryCode
, SUM(c.Population) AS hap
FROM
city AS c
GROUP BY c.CountryCode
WHERE
hap > 2000000;
// 안 됨
SELECT
c.CountryCode
, SUM(c.Population) AS hap
FROM
city AS c
GROUP BY c.CountryCode
HAVING hap > 2000000;
// HAVING으로 조건 걸어주면 됨
=============================================================
CASE ~ WHEN ~ THEN ~ ELSE END
- WHEN과 THEN은 한 쌍이다.
- WHEN과 THEN은 여러 개 존재할 수 있다.
- ELSE를 사용하여 조건에 맞지 않을 때, 출력할 값을 작성할 수 있다.
-- SELECT에 CASE문 사용
SELECT
c.Name
, (CASE
WHEN c.Population >= 9000000
THEN '대도시 입니다.'
WHEN c.Population >= 5000000
THEN '중급 도시네요'
ELSE '작은 도시입니다.'
END) AS '도시타입'
FROM
city AS c
WHERE
c.CountryCode = "KOR";

-- 구매자 아이디, 이름, 총 구매 금액, 총 구매 금액을 기준으로 나눈 등급 조회
-- 총 구매 금액을 기준으로 내림차순 정렬
SELECT
O.o_id AS 'id'
, M.m_name AS 'name'
, SUM(O.o_amount * G.g_price) AS 'total'
, (CASE
WHEN SUM(O.o_amount * G.g_price) >= 30000000 THEN 'VIP 등급 고객'
WHEN SUM(O.o_amount * G.g_price) >= 20000000 THEN 'Daiamond 등급 고객'
WHEN SUM(O.o_amount * G.g_price) >= 10000000 THEN 'Gold 등급 고객'
WHEN SUM(O.o_amount * G.g_price) >= 8000000 THEN 'Silver 등급 고객'
WHEN SUM(O.o_amount * G.g_price) >= 5000000 THEN 'Bronze 등급 고객'
ELSE '일반 회원'
END) AS 'order level'
FROM
tb_order AS O
INNER JOIN
tb_member AS M
ON
O.o_id = M.m_id
INNER JOIN
tb_goods AS G
ON
O.o_g_code = G.g_code
GROUP BY M.m_id
ORDER BY total DESC;
-- CASE문 단독 사용
DELIMITER $$
CREATE PROCEDURE proc_grade_case(IN memId VARCHAR(50))
COMMENT '회원의 아이디를 입력 받아 레벨을 조회하는 프로시저'
BEGIN
DECLARE memLv INT DEFAULT 0; -- 변수 선언과 동시에 초기화 하기
SELECT
M.m_level INTO memLv
FROM
tb_member AS M
WHERE
M.m_id = memId;
CASE
WHEN(memLv = 1) THEN
SELECT '관리자' AS '권한';
WHEN(memLv = 2) THEN
SELECT '판매자' AS '권한';
WHEN(memLv = 3) THEN
SELECT '구매자' AS '권한';
ELSE
SELECT '회원' AS '권한';
END CASE;
END $$
DELIMITER ;
CALL proc_grade_case('id005');'Database > MYSQL' 카테고리의 다른 글
| 23.05.15 / DBeaver(디비버) (0) | 2023.05.15 |
|---|---|
| 23.05.15 / 데이터 타입 (0) | 2023.05.15 |
| 23.05.08 / DBMS (0) | 2023.05.09 |
| 23.04.04 / [select 쿼리 실행 - 리스트 출력] jsp - mysql 연결하기(JDBC) (0) | 2023.04.04 |
| 23.03.29 / [insert 쿼리 실행] jsp - mysql 연결하기(JDBC) , mysql 드라이버이해하기 (0) | 2023.03.29 |