세계에서 가장 많이 쓰이는 오픈소스 관계형 데이터베이스 관리시스템 (RDBMS, Relational DataBase Management System).
SQL = Query = 질의 = 내가 원하는 데이터에 대한 질의를 한다
테이블 = 데이터가 저장되어 있는 곳 (행과 열로 이루어져 있음)
SELECT * FROM db;
select * from db;
SeLecT * FrOm db;
# 다같은 결과를 보여줌
1. # 주석달기
2. -- 주석달기
3. /* 주석 여러 줄
달기
헿 */
-- CREATE DATABASE [DB 이름];
CREATE DATABASE TestDB;
-- CREATE DATABASE [DB 이름] CHARACTER SET [character set];
CREATE DATABASER TestDB CHARACTER SET utf8;
-- USE [DB 이름];
USE TestDB;
-- DROP DATABASE [DB 이름];
DROP DATABASE TestDB;
-- CREATE TABLE [Table 이름] ([Field 이름1][데이터 타입1], [Field 이름2][데이터 타입2]...);
CREATE TABLE Test
(
YYYMMDD DATE,
ID INT,
Name VARCHAR(30),
AGE INT
);
-- DROP TABLE [Table 이름];
DROP TABLE Test;
-- ALTER TABLE [Table 이름] ADD [Column 이름][데이터 타입];
ALTER TABLE Test ADD GENDER VARCHAR(20);
-- ALTER TABLE [Table 이름] MODIFY [Field 이름][데이터 타입];
ALTER TABLE Test MODIFY AGE VARCHAR(20);
-- ALTER TABLE [Table 이름] DROP [Field 이름];
ALTER TABLE Test DROP Gender;
-- ALTER TABLE [Table 이름] RENAME COLUMN [변경 전 Field 이름] TO [변경 후 Field 이름];
ALTER TABLE Test RENAME COLUMN NAME TO NAMES;
-- INSERT INTO [Table 이름] ([Field 이름1], [Field 이름2], [Field 이름3], ...) VALUES ([Value 1], [Value 값2], [Value 값3], ...);
INSERT INTO Test (YYMMDD, ID, NAMES, AGE, GENDER) VALUES ('2022-12-01', 00001, '홍길동', '20', 'M');
-- 만약 필드 이름을 생략한다면, 데이터베이스의 스키마와 같은 순서대로 필드의 값이 자동 대입된다.
-- UPDATE [Table 이름] SET [Field 이름]=[Value] WHERE [Field 이름] = [조건 데이터 값];
UPDATE Test SET AGE = '30' WHERE NAMES = '홍길동';
-- DELETE FROM [Table 이름] WHERE [Field 이름] = [조건 데이터 값];
DELTE FROM Test WHERE NAMES = '홍길동';
-- SELECT * FROM [Table 이름];
SELECT * FROM Test;
SELECT * # * = 테이블에 있는 모든 항목을 보겠다
FROM table_name
LIMIT 10;
# 10줄만 보여주겠다
SELECT price, name
FROM table_name
LIMIT 10;
/*
SELECT
[Table 이름1].[Field 이름1],
[Table 이름1].[Field 이름2],
[Table 이름2].[Field 이름1]
FROM [기준 Table 이름]
(INNER(교집합)/FULL(합집합)/LEFT(왼쪽 기준)/RIGHT(오른쪽 기준)) JOIN [조인 Table 이름]
ON [기준 Table 이름].[기준 Key] = [조인 Table 이름].[기준 Key];
*/
SELECT
TEST1.ID, TEST1.NAMES, TEST1.AGE, TEST1.GENDER, TEST2.Type
FROM TEST1
INNER JOIN TEST2
ON TEST1.ID = TEST2.ID;
SELECT a.dong, a.nm, a.price, b.gu, b.dong
FROM table1 a, table2 b
WHERE a.column = b.column;
SELECT a.dong, a.dong, b.nm, b.size, b.price
FROM area_cd a
LEFT OUTER_JOIN apt_list b
ON a.area_cd = b.area_cd
AND b.con_year = 2020
;
-- SELECT [Field 이름] FROM [Table 이름] GROUP BY [Field 이름];
SELECT * FROM TEST GROUP BY NAME;
-- Field별로 개수 세기 = COUNT, Field별로 합 구하기 = SUM
-- SELECT [Field 이름], COUNT(Field 이름), SUM(Field 이름) FROM [Table 이름] GROUP BY [Field 이름];
SELECT NAME, COUNT(NAME), SUM(PRiCE) FROM TEST GROUP BY NAME;
-- 그룹화 후 조건에 맞는 값만 가지고 오고 싶을 때
-- SSELECT [Field 이름], COUNT(Field 이름), SUM(Field 이름) FROM [Table 이름] GROUP BY [Field 이름] HAVING [조건];
SELECT NAME, COUNT(NAME), SUM(PRiCE) FROM TEST GROUP BY NAME HAVING SUM(PRICE) > 1000;
SELECT *
FROM table_name
ORDER BY price #desc (내림차순);
SELECT *
FROM table_name
ORDER BY year desc, month desc, day desc;
SELECT count(*)
FROM table_name;
# tabel_name 안의 데이터 개수(행의 개수)를 셀 때 사용
SELECT column_name, count(*)
FROM table_name
GROUP BY column_name;
# column_name별로 GROPU BY 되어 데이터 개수가 세어지게 된다
# dong, count(*) 열을 가지게 됨 (SELECT 뒤에 오는거)
SELECT column2_name, count(*)
FROM table_name
GROUP BY column2_name;
# column2_name별로 GROUP BY 되어 데이터 개수가 세어지게 된다
# GROUP BY는 일단 중복제거가 된다 !
SELECT *
FROM table_name
WHERE column_name = 'A'
LIMIT 100;
SELECT *
FROm table_name
WHERE column_name = 'A'
AND column2_name = 1
LIMIT 100;
# A 그리고 1인 데이터
SELECT *
FROm table_name
WHERE column_name = 'A'
OR column2_name = 1
LIMIT 100;
# A 이거나 1인 데이터
# 구간을 나눌 때 사용 (?)
SELECT price, year, month, day, nm,
CASE WHEN price <= 10000 then '1억 이하'
WHEN price <= 30000 then '1억~3억 이하'
WHEN price > 30000 then '3억 초과'
END
FROM table_name
LIMIT 100;
==
SELECT price, year, month, day, nm,
CASE WHEN price <= 10000 then '1억 이하'
WHEN price <= 30000 then '1억~3억 이하'
ELSE '3억 초과'
END
FROM table_name
LIMIT 100;

SELECT *
FROM table_name
WHERE NM LIKE '%자이%'
# %자이%라고 했기 때문에 자이가 어디든 포함된 데이터들이 추출이 됨
# 자이%라면 자이 ~~ 인 데이터만 추출이 되고
# %자이라면 ~~ 자이 인 데이터만 추출이 된다
LIMIT 100;
# NM에 자이가 포함된 데이터들만 추출이 됨
SELECT *
FROM table_name
WHERE NM LIKE '%자이%'
LIMIT 100;
# 자이가 포함되지 않은 데이터들만 추출이 됨
SELECT *
FROM (
SELECT DONG, COUNT(*) CNT
FROM table_name
GROUP BY DONG
) a
WHERE CNT > 100

SELECT a.*
, CASE WHEN CNT < 200 THEN '200미만의 거래 지역'
ELSE '200이상의 거래 지역'
END
FROM (
SELECT DONG, COUNT(*) CNT
FROM table_name
GROUP BY DONG
) a

SELECT SUM(price), MIN(price), MAX(price), AVG(price)
FROM apt_list
WHERE year = 2020;
SELECT year, SUM(price), MIN(price), MAX(price), AVG(price)
FROM apt_list
GROUP BY year
;
SELECT '빌라', nm, size, price
FROM list
WHERE DAY = 31
AND size = 29
;
SELECT '아파트', nm, size, price
FROM list
WHERE DAY = 31
AND size = 60
AND year = 2021
AND price = 3000
;
SELECT '빌라', nm, size, price
FROM list
WHERE DAY = 31
AND size = 29
UNION all
SELECT '아파트', nm, size, price
FROM list
WHERE DAY = 31
AND size = 60
AND year = 2021
AND price = 3000
;
SELECT '빌라', nm, size, price
FROM list
WHERE DAY = 31
AND size = 29
UNION
SELECT '아파트', nm, size, price
FROM list
WHERE DAY = 31
AND size = 60
AND year = 2021
AND price = 3000
;
/*
0. UNION 이든지 UNION ALL이든지 사실 그리 좋은 SQL 작성은 아니다.
UNION이 필요하다는 것은 사실 두 엔터티(테이블)가 하나의 엔터티(테이블)로 통합이 되었어야
할 엔터티들이었는데, 알 수 없는 이유로 분리 운영되는 경우가 상당히 많다.
즉 모델링 차원에서 엔터티를 적절히 통합하여 UNION의 요건을 모두 제거하자.
1. 두 집합에 절대 중복된 튜플(레코드)가 발생할 수 없다는 보장이 있다면 UNION ALL을 꼭 사용하자.
두 집합에서 모두 각각의 PK를 조회하는데, 그 두 집합의 PK가 절대 중복되지 않는 형태
2. 중복이 있다 하더라도 그리 문제되지 않는다면 UNION 보다는 UNION ALL을 사용하자.
3. 만약 UNION이나 UNION ALL을 사용해야 한다면, 최소 필요 컬럼만 SELECT 하자.
출처:토토님 http://intomysql.blogspot.com/2011/01/union-union-all.html
*/