DB

쿼리

원2 2024. 7. 16. 18:10
728x90
반응형

IN 연산자

SELECT * 
FROM employees 
WHERE department IN ('Sales', 'Marketing', 'HR');

employees 테이블에서 department 의 값이 위의 셋 중하나 인 것을 출력

 

IN 연산자 & 서브쿼리

SELECT title 
FROM songs 
WHERE artist IN (
    SELECT name 
    FROM artists 
    WHERE genre = 'Pop'
);

서브쿼리 ( ) 부터 시작 

artists 테이블에서 genre 가 pop 인 아티스트의 이름을 선택

외부쿼리 : songs 테이블에서 해당 아티스트의(해당 값을 가지고 있는) 노래 제목을 선택

 

 

LIKE 연산자

 

집계 쿼리

 

별칭 붙이기 : AS ~~

 

HAVING

: 각 열의 개별 값이 아니라 그룹으로 묶인 결과에 대해서 조건을 적용

그룹으로 묶인 행에는 SUM, MIN, MAX, AVG 등 일반적으로 작동하는 어떤 집계 함수도 적용

SELECT author, AVG(words) AS avg_words 
FROM books 
GROUP BY author
HAVING avg_words >= 150000;

AS 를 사용하여 AVG(words) 의 별칭을 avg_words 로 설정

books 테이블에서 데이터를 가져옴

GROUP BY 를 사용하여 author 열을 기준으로 그룹화

HAVING 을 사용하여 조건에 맞는 데이터 선택, HAVING 절은 GROUP BY 결과에 대한 조건을 지정하는데 사용됨

 

CASE

SELECT count(*) AS student_count,
       CASE
           WHEN number_grade > 90 THEN 'A'
           WHEN number_grade > 80 THEN 'B'
           WHEN number_grade > 70 THEN 'C'
           ELSE 'F'
       END AS letter_grade
FROM student_grades
GROUP BY letter_grade;


student_count | letter_grade
--------------|--------------
2             | A
2             | B
1             | C
1             | F

- count(*) : 그룹의 학생 수 계산

- CASE : if 나 switch 같은 조건문

- AS : 별칭 설정

- GROUP BY : 그룹화 하여 등급별 학생 수 계산

 

INNER JOIN

SELECT persons.name AS person_name, hobbies.name AS hobbies
FROM persons
JOIN hobbies
ON persons.id = hobbies.person_id
WHERE persons.name = 'Bobby McBobbyFace';

id | name
1  | Bobby McBobbyFace
2  | Alice Wonderland


id | person_id | name
1  | 1         | Swimming
2  | 1         | Reading
3  | 2         | Hiking



persons.name        | hobbies.name
--------------------|--------------
Bobby McBobbyFace   | Swimming
Bobby McBobbyFace   | Reading

- FROM persons 주체가 될 테이블 하나 정하기

- INNER JOIN 할 테이블

- ON : 조건 설정

- 결합한 테이블에서 출력 조건 설정

 

LEFT OUTER JOIN

SELECT customers.name, customers.email, 
       sum(orders.price) AS total_spent
FROM customers
LEFT OUTER JOIN orders
ON customers.id = orders.customer_id
GROUP BY customers.id
ORDER BY total_spent DESC;


id | name     | email
1  | Alice    | alice@example.com
2  | Bob      | bob@example.com
3  | Charlie  | charlie@example.com


id | customer_id | price
1  | 1           | 100.00
2  | 1           | 150.00
3  | 2           | 200.00
4  | 3           | 50.00
5  | 3           | 75.00



name     | email              | total_spent
---------|--------------------|-------------
Bob      | bob@example.com    | 200.00
Alice    | alice@example.com  | 250.00
Charlie  | charlie@example.com| 125.00

- 동작방식

- LEFT 왼쪽 테이블에서 모든 행을 가져오라고 명령

- OUTER 가져오려는 오른쪽 테이블에 일치하는 항목이 없어도 행을 유지해야한다고 명령

- ON 조인 조건

- GROUP BY 고객 별로 그룹화, 행에서 고유할 가능성이 가장 높은 열에서는 항상 사용

- ORDER BY ~ DESC; 내림차순 정렬

 

SELF JOIN

SELECT released.title AS released_title, 
       sequel.title AS sequel_title
FROM movies AS released
LEFT OUTER JOIN movies AS sequel
ON released.sequel_id = sequel.id;

id | title             | sequel_id
1  | The Matrix        | 2
2  | The Matrix Reloaded | 3
3  | The Matrix Revolutions | NULL
4  | Inception         | NULL



released_title       | sequel_title
---------------------|-----------------------
The Matrix           | The Matrix Reloaded
The Matrix Reloaded  | The Matrix Revolutions
The Matrix Revolutions | NULL
Inception            | NULL

- 두개의 별칭을 사용하여 각 영화와 그 후속작이 있는 테이블

- 조인 조건으로 현재의 released.id 와 후속작 sequel.id 를 연결

- 다음 후속작이 없는 경우 NULL (left outer join)

 

UPDATE

UPDATE documents
SET author = 'Jackie Draper'
WHERE author = 'Jackie Paper';

-  documents 테이블에서 author 컬럼의 값을 찾아서 수정

 

DELETE

DELETE FROM documents
WHERE title = "Things I'm Afraid Of";

- documents 테이블에서 title 의 컬럼의 값을 찾아서 삭제

- 참고로 실제로 삭제하는 일이 드물고 '삭제됨' 이라는 행을 하나 추가해서 true, false 로 표기하는 경우가 많음

 

ALTER

ALTER TABLE clothes ADD price INTEGER;

- 이미 생성되어 있는 테이블이 price 라는 컬럼을 추가

 

INSERT INTO clothes VALUES (4, "pants", "mydesign", 40);

- 새로운 행를 추가

 

Drop

잘가고

 

안전하게 SQL 사용하기

잘못된 업데이트 / 삭제 방지

update 문을 실행하기 전에 올바른 열과 행을 업데이트 하는지 확인하기

// 아래의 sql 을 실행하기 전에
UPDATE users SET deleted = true WHERE id = 1;

// 먼저 확인해보기
SELECT id, deleted FROM users WHERE id = 1;

 

업데이트를 하기로 결정하면 LIMIT 을 사용해서 실수로 너무 많은 행을 업데이트 하지 않도록 조정

// 업데이트의 경우
UPDATE users SET deleted = true WHERE id = 1 LIMIT 1;

// 삭제의 경우
DELETE users WHERE id = 1 LIMIT 1;

 

트랜잭션

db를 어떤 식으로든 변경하는 SQL 명령을 내리면 트랜잭션이 시작됨

트랜잭션은 단일 논리적 작업(은행 거래..)으로 처리되는 일련의 작업, 트랜잭션은 안정적으로 처리되도록하기 위해

ACID원칙을 준수해야함.

 

ACID - 오류, 정전 및 기타 사고에도 데이터 유효성을 보장하기 위한 db 트랜잭션의 속성 집합

  • 원자성 : 트랜잭션이 완전히 성공하거나 완전히 실패하도록 되어야함
  • 일관성 : 트랜잭션이 db를 하나의 일관된 상태에서 다른 일관된 상태로만 가져올 수 있도록 보장, 불변성을 보존
  • 고립성 : 트랜잭션의 동시 실행이 트랜잭션이 순차적으로 실행된 경우와 동일한 상태로 db를 유지하도록 보장
  • 내구성 : 트랜잭션이 커밋되면 시스템 장애가 발생하더라도 커밋된 상태로 유지 (비휘발성)

한 트랜잭션 안에 여러 명령을 래핑하는법

BEGIN TRANSACTION;
UPDATE people SET husband = "Winston" WHERE user_id = 1;
UPDATE people SET wife = "Winnefer" WHERE user_id = 2;
COMMIT;

- 에러가 생겨서 db가 두 명령을 실행하지 못하면 원래대로 롤백됨

- 동일한 데이터에서 작동하지 않게 하려고 할때도 사용 

 

백업 만들기

주기적으로 데이터를 백업해 두는게 좋음, 만약 날라가서 없는  것 보단 예전거라도 있는게 훨 나음

 

복제

db의 사본을 저장, 하여 예측불가한 상황에 놓였을 때 바로 사용가능할수 있도록 하는 대비책 but 성능저하 생각해얗마

 

권한 부여

db 전체에 대한 액세서 권한은 몇명정도만 유지

 

728x90
반응형