[DBMS] 관계형 데이터베이스 SQL 고급 명령어

Suji Kang·2023년 9월 14일
0

기본적인 SELECT문

컬럼 골라내기 (SELECT a, b)
행 골라내기 (WHERE 절)

🐾 정렬하여 조회하기(ORDER BY)

최신순, 오래된순, 좋아요순, ....

SELECT 컬럼1, 컬럼2, 컬럼3
FROM 테이블명
WHERE 조건
ORDER BY 컬럼 옵션;

📍 옵션

🔎문법

ASC
오름차순 (작은값 👉 큰값)
DESC
내림차순 (큰값 👉 작은값)

📝예제

나이가 작은순에서 큰순
SELECT * FROM tbl_tmp;
ORDER BY age ASC;

나이가 많은순에서 작은순
SELECT * FROM tbl_tmp;
ORDER BY age DESC;

📌 컬럼 이름에 별명 붙이기(alias)

SELECT id AS "아이디", name AS "사용자 이름", age AS "나이" 
FROM tbl_tmp;

🔎 AS 는 생략가능
""는 컬럼의 별명을 이미 사용되고 있는 예약어(명령어)로 사용하거나 띄어쓰기가 포함된 별명을 사용하는 경우를 제외하고는 생략가능

SELECT
  a  AS "안녕",
  b "반가워",
  c AS 가격,
  d cnt
# AS 를 사용하여 컬럼명을 변경할 수 있다.(별명)
# 🌟 정석으로 쓰는 방법
SELECT id AS "아이디", name AS "이름", age AS "나이" 
FROM tbl_tmp;

# 줄여서(생략) 쓰는 방법
SELECT id 아이디, name 이름, age 나이 
FROM tbl_tmp;

# 뛰어쓰기가 있는 컬럼명은 반드시 ""로 감싸줘야 한다.
SELECT id AS 아이디, name AS "사용자 이름", age AS 나이 
FROM tbl_tmp;

# oder by 사용 (별명으로도 사용 가능)
📍 오름차순
SELECT * FROM tbl_tmp 
ORDER BY age ASC;
📍 내림차순
SELECT * FROM tbl_tmp O
RDER BY 나이 DESC;

54:00/9/13
📝 일단은 tbl_posts 테이블을 하나 만든다.

CREATE TABLE tbl_posts(
    post_id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(100),
    contents VARCHAR(200),
    writer INT,
    CONSTRAINT tbl_posts_writer_fk 
    FOREIGN KEY (writer) REFERENCES tbl_tmp (id)
);

여기서 값을 삽입해보자 ❗️
존재하는값을 넣어보자

🐾 INSERT

새로운 레코드를 추가하는 명령어

INSERT INTO tbl_posts 
(post_id, title, contents, writer) 
VALUES 
(100, 'sql을 배워봅시다', 'sql 꿀팁을 알려줄게 오늘!', 20);


# tbl_tmp의 id 컬럼에 4645가 없기에
# tbl_posts의 writer 컬럼에 4645가 저장될수 없다 (외래키 제약조건위반)
INSERT INTO tbl_posts 
(post_id, title, content, writer) 
VALUES 
(2315, 'js을 배워봅시다', 'js 꿀팁을 알려줄게 오늘!', 4645);

INSERT INTO tbl_posts 
(post_id, title, content, writer) 
VALUES 
(2315, 'js을 배워봅시다', 'js 꿀팁을 알려줄게 오늘!', 40);

INSERT INTO tbl_posts 
(post_id, title, content, writer) 
VALUES 
(105, '오늘 뭐먹을까요?', '오늘저녁 메뉴 추천좀 ', 20);

INSERT INTO tbl_posts 
(post_id, title, content, writer) 
VALUES 
(50, '안녕하세요', '반가워', null);

🐾 두개의 테이블을 합치기 ❓

JOIN 을 사용한다

📌 내부/동등조인 (inner join /equi join)

🐾 INNER JOIN

두개의 테이블을 합치긴 할건데, 조건을 🌟만족🌟하는 행들끼리 합치겠다.

📍 EQUI(등가) JOIN은 두 개의 테이블 간에 컬럼 값들이 서로 정확하게 일치하는 경우에 사용되는 방법으로 대부분 PK- FK의 관계를 기반으로 합니다.

📍 Inner join은 = , <> , > , < 와 같은 oeprator를 사용할 수 있는 반면 Equi join은 = 만 사용하는 경우를 의미한다.

두개의 table을 한개의 table 로 만들거야 ❗️


tbl_posts table 에서의 writer하고 tbl_tmp table 에서의 id 가 같으면 table 을 합쳐줘.

🔎문법

SELECT 컬럼1, 컬럼2, 컬럼3, ...
FROM 테이블명1 INNER JOIN 테이블2
ON 조인조건
[WHERE 조건]
[ORDER BY 컬럼 옵션]

📝예제

# 내부조인
SELECT tbl_posts.title, tbl_tmp.name
FROM tbl_posts INNER JOIN tbl_tmp 
ON tbl_posts.writer = tbl_tmp.id;

테이블마다 tbl_posts. tbl_tmp. 쓰기엔 너무 긴거같은데..❓


그러면, 테이블이름대신 별명을 짓자 ❗️
🔎문법

# 테이블 이름에 별명짓기 (AS 사용 🚫)
SELECT tp.title 별명, tt.name 별명
FROM   tbl_posts 별명
INNER JOIN tbl_tmp 별명
ON 별명.writer = 별명.id;

📝예제

# 테이블 이름에 별명짓기 (AS 사용 🚫)
SELECT tp.title 제목, tt.name 작성자
FROM   tbl_posts tp
INNER JOIN tbl_tmp tt
ON tp.writer = tt.id;

조건에 🌟만족하지 않으면🌟 ❓

left 또는 right 에 기준으로 손실없이 테이블이 없애지않고 볼수있다.

🐾 OUTER JOIN

(1) LEFT OUTER JOIN

🔎문법

# LEFT OUTER JOIN
#왼쪽에 있는 테이블의 행을 모두 보겠다 (손실없이)
SELECT *
FROM <첫 번째 테이블(LEFT 테이블)>
LEFT OUTER JOIN <두 번째 테이블(RIGHT 테이블)>
ON <조인 조건>

📝예제

# 📍 LEFT OUTER JOIN
#왼쪽에 있는 테이블의 행을 모두 보겠다 (손실없이)
SELECT *
FROM tbl_posts tp LEFT OUTER JOIN tbl_tmp tt
ON tp.writer = tt.id;

🔎 결과:

기준은 왼쪽 (왼쪽 테이블엔 손실이 없다)
오른쪽에 조건이 맞지 않는 것들은 null 값으로.

(2)RIGHT OUTER JOIN

🔎문법

#📍 RIGHT OUTER JOIN
#오른쪽에 있는 테이블의 행을 모두 보겠다 
SELECT *
FROM <첫 번째 테이블(LEFT 테이블)>
RIGHT OUTER JOIN <두 번째 테이블(RIGHT 테이블)>
ON <조인 조건>

📝예제

# 📍 RIGHT OUTER JOIN
#오른쪽에 있는 테이블의 행을 모두 보겠다 
SELECT *
FROM tbl_posts tp RIGHT OUTER JOIN tbl_tmp tt
ON tp.writer = tt.id;

🔎 결과:

기준은 오른쪽 (오른쪽 테이블엔 손실이 없다)
왼쪽에 조건이 맞지 않는 것들은 null 값으로.


🐾 산술연산자 사용가능

원래 age에서 age+10 산술연산자를 통해 값을낼수있음
( + , - , * , / )

SELECT * 
FROM tbl_tmp;

SELECT age, age + 10
FROM tbl_tmp;

🐾 날짜 데이터

🔎문법

ALTER TABLE tbl_tmp
ADD join_date DATE;
날짜 형식 패턴 (그때그때 찾아서 쓰면됨 외울필요 없음)
    %m :  두글자 월 03, 04, 05, ...
    %M : March, May, ...
    %d :  두글자 일
    %D :  1st, 2nd, 3rd, 4th, ...
    %Y :  네글자 연도
    %y :  두글자 연도
    %h :  두글자 시간 (12시간제) 00-12
    %H :  두글자 시간 (24시간제) 00-23
    %i :  두글자 분
    %s :  두글자 초

📝예제

INSERT INTO tbl_tmp
(id, name, age, join_date) 
VALUES 
(70, '김철수', 30,  STR_TO_DATE('2020-01-01', '%Y-%m-%d'));

INSERT INTO tbl_tmp
(id, name, age, join_date)
VALUES 
(80, '김영희', 20, now());

# 현재시간 출력
ALTER TABLE tbl_tmp
ADD join_date DEFAULT NOW();

🐾 데이터수정

🔎문법

UPDATE 테이블명
SET 컬럼명 =, 컬럼명 =, ...
WHERE 조건;

📝예제

# 데이터 수정
UPDATE tbl_tmp
SET name ='이슬이', age = 25;
WHERE id = 20;

UPDATE tbl_tmp
SET  join_date = now()
WHERE join_date IS NULL;
#join_date가 null 인것,

# ORACLE 가능, MYSQL은 기본적으로 SAFE MODE가 적용되어
# PRIMARY KEY 가 아닌 조건으로 행을 골라내어 수정하는것을 막아준다
UPDATE tbl_tmp
SET  join_date = now()
WHERE id <= 60;

🐾 데이터삭제

🔎문법

DELETE FROM 테이블명
WHERE 조건;

📝예제

# 데이터 삭제
DELETE FROM tbl_tmp
WHERE id = 50;
#id 50은 삭제됨.

DELETE FROM tbl_tmp
WHERE id = 70;
#--> id 70은 왜 삭제가 안될까?
#외래키 제약조건 때문에 삭제가 안된다.

# 외래키 제약조건을 삭제하고 싶다면?
#부모의 값이 삭제되면 자식의 값도 삭제
#혹은 자식의 값을 null로 자동으로 바꿔주는 옵션을 만들수 있음 
CREATE TABLE tbl_a (
    id INT PRIMARY KEY AUTO_INCREMENT,
    pw VARCHAR(20);
);

INSERT INTO tbl_a
 (pw) 
 VALUES ('1234');



CREATE TABLE tbl_b(
	post_id int primary key,
    writer int ,
    constraint fk foreign key (writer) 
		references tbl_a (id) on delete cascade
);

INSERT INTO tbl_b
VALUES(300, 3);

SELECT * FROM tbl_b;

DELETE FROM tbl_a 
WHERE id = 3;

📌 데이터 추가 시에는

부모에 없는 값을 자식테이블에 추가할수 없다

📌 데이터 삭제 시에는

 자식에서 사용되고 있는 값을 부모에서 삭제할수 없다
 자식에서 사용되고 있는 값이 부모에서 삭제된다면 자동으로
 자식에서도 삭제가 되게 만드는 옵션 : ON DELETE CASCADE
 
 자식에서 사용되고 있는 값이 부모에서 삭제된다면 자동으로
 자식의 값을 NULL 로 바꾸는 옵션 : ON DELETE SET NULL
profile
나를위한 노트필기 📒🔎📝

0개의 댓글