데이터베이스의 상태를 변화시키기 위한 일련의 연속적이 작업들의 모음
거래과정 전체가 있을때 모든 과정이 원활하게 되서 완료까지 된 것
이 과정이 전부 일어난 다음에는 commit을 해주어야 DB에 입력
정상적으로 일어났다고 말할 수 있음
하나의 트랜잭션의 안정성을 보장하기 위한 성질
Atomicity(원자성) : 전체가 완료가 되어야 하나의 트랜잭션이 일어난 것. 하나의 오류도 있으면 안된다는 것
전부 성공하거나 실패해야함
consistency(일관성) : DB의 규칙이 잘 준수되도록 테이블을 구성하고, 그에 맞게 활용하는 것. NULL허용을 하지 않는 것 자체도 일관성 유지!
데이터베이스의 제약을 따라야함
Isolation(고립,독립성) : 작업을 하는데 있어서 둘간에 간섭이 있지 않고 별개로 일어나게 하는 것
각각의 트랜잭션은 독립적이어야함
ex) 내가 2만원 가지고 있을 때, 넷플 1.7, 디플 .99 결제 불가능
Durability(연속성) : 한번 정해지면 바뀌지 않는다. 1원을 송금한 기록이 사라지지 않고 지속적으로 남아 있어야 된다
해당 기록은 영구적이어야함
트랜잭션과 ACID 속성이 중요한 작업 → RDB로 작업해보자
(관계형DB로 작업해보자)
SELECT CustomerID, AVG(Total)
FROM invoices
WHERE CustomerID >= 10;
where조건. 아이디와 평균 가져와라. invoices에서
SELECT CustomerID, AVG(Total)
FROM invoices
WHERE CustomerID >= 10
GROUP BY CustomerId
HAVING SUM(Total)>=30
ORDER BY 2;
❗ where와 having의 차이
: where은 레코드 하나하나에 대한 조건을 거는 것이고,
having은 그룹 전체에 대한 조건을 거는 것
그래서 where절 다음에 group by절을 사용해야하고, group by절 다음에 having절을 사용한다.
🔑 실행 순서
FROM→ON→JOIN→WHERE→GROUP BY→HAVING→SELECT→ORDER BY
🔑 작성 순서
SELECT→FROM→JOIN→ON→WHERE→GROUPBY→HAVING→ORDER BY
procedure : state → sprit → apply (count,sum...) → combine
순서 : 상태 → 분할(key=id) → 적용(집계연산) → 결합
❓ QnA
Q. 명령어가 조금씩 다른 것 같아요.
A. 데이터베이스 설계할때마다 특징이 있는데, 이때 효율적으로 관리하기 위해서 command가 조금씩 달라질 수 있다.
(https://www.sqlitetutorial.net/sqlite-sample-database/)
sql 사용시에는 각각 데이터를 다루기 전에 어떻게 데이터들이 이루어져있는지 확인하고 진행하는 것이 좋다
SELECT * FROM Customers
GROUP BY State;
state를 중심으로 그룹핑되어 나타남. 여러개 있다면 상위 첫번째 레코드가 조회됨
SELECT state, COUNT(*) FROM Customers
GROUP BY State;
평균과 합계, 통계적인 것에 같이 사용하는게 더 유의미
group by를 하려는 것은 집계하기 위함. (개수를 세거나, 평균을 내거나, 표준편차를 내거나...통계)
SELECT state, COUNT(*) FROM Customers
GROUP by State
ORDER by State DESC;
기본 설정은 ASC 오름차순 (생략 가능). DESC 내림차순
SELECT CustomerId, AVG(Total) avgtotal
FROM invoices
GROUP BY CustomerId
HAVING avgtotal > 6.00;
그룹화한 결과에 대한 필터. 즉 group by의 결과에 대한 필터
SELECT CustomerId,
COUNT(CustomerId) InvoiceCnt,
AVG(Total) AvgTotal,
SUM(Total) SumTotal,
MAX(Total) MaxOfTotal
FROM invoices
GROUP BY CustomerId;
SELECT
CustomerId,
(
CASE
WHEN CustomerId <= 25 THEN 'GROUP 1'
WHEN CustomerId <= 50 THEN 'GROUP 2'
ELSE 'GROUP 3'
END
) GRP
FROM customers
ORDER BY CustomerId;
sql문에서 if 사용하는 것과 같음
조건을 넣어서, 반환값은 필드 하나가 오는 것이 일반적
FROM에도 사용가능함
SELECT CustomerId, CustomerId = 2
FROM customers
WHERE CustomerId < 6;
=
SELECT CustomerId, CustomerId = (SELECT CustomerId FROM customers WHERE CustomerId = 2)
FROM customers
WHERE CustomerId < 6;
SELECT *
FROM customers
WHERE CustomerId IN (3, 6, 9);
3,6,9에 해당하는 customers 가 출력
그가 아닌 것을 출력하고 싶다면 IN 대신에 NOT IN 사용
개인적으로 비교해보기. N413에 rf로 존재함~~~
그중에서 새롭게 배운(?) 것들 위주로 적어둠
tips.iloc[3:8, :]
=
SELECT *
FROM tips
LIMIT 5 OFFSET 3;
pd.concat([df1, df2])
=
SELECT city, rank
FROM df1
UNION ALL
SELECT city, rank
FROM df2
tips.iloc[3:8,:] # 3:8은 행(3-7출력), 뒤에 :는 열, row 추출
SELECT CustomerId, UPPER(c.City) || ' '|| UPPER(c.Country) AS Country
FROM Customers c;
SELECT SUBSTRING(LOWER(FirstName),1,4)||SUBSTRING(LOWER(LastName), 1,2) new_customerId
FROM customers;
CREATE TABLE Teachers(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(30),
subject VARCHAR(10) NOT NULL,
salary INTEGER);
이렇게 설정해주면 아래처럼 id값 넣지 않아도 insert 가능
INSERT INTO Teachers(name, subject, salary)
VAlues ('Spongebob', 'Math', 3500);
SELECT teacher_id, student_id, ROW_NUMBER() OVER (ORDER BY (select null)) '전체 학생순서'
FROM Student;
SELECT teacher_id, student_id, ROW_NUMBER() OVER (PARTITION BY teacher_id ORDER BY (teacher_id)) '선생님별 학생순서'
FROM Student;
SELECT student_id, age as '중앙값'
FROM Student
LIMIT 1
OFFSET (SELECT COUNT(*)
FROM Student) / 2;
💌 오늘의 회고
오늘 교수님(?)이 코딩은 암기가 기본이라고 하셨다. 나는 외우는거 글케 못하는디... 머리를 열어서 바꿀 수도 없고. 많이 해보면 외워지는거 아닌가? 싶기도~ 어제 배운 것의 연장선이라서 괜찮았다. sql문이 개인적으로 더 쉽게 느껴지는 것 같은데 뭔가 명확해서 그런듯. select, from, where로만 하면 되기도 하고, 여러 함수 사용안해도 되서 그런가 ㅋㅋ.. 아직 sql의 기본만 다뤄서 그런 것 같기도 하지만,,, 쨌든! 흥미가 있어서 재밌게 따라가는 중. 수학문제 풀듯 해결되는 점이 아주 마음에 든다.