Notice
Recent Posts
Recent Comments
Link
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

어리바리 신입 개발자의 얼렁뚱땅 개발 기록 ✨

23.05.09 / SELECT, WHERE AND/OR , BTEWEEN, LIKE, CASE 본문

Database/MYSQL

23.05.09 / SELECT, WHERE AND/OR , BTEWEEN, LIKE, CASE

낫쏘링 2023. 5. 9. 16:00
728x90

[데이터베이스 선택 가이드]

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');
728x90