-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSQL_Aplied2.sql
More file actions
162 lines (133 loc) · 4.45 KB
/
SQL_Aplied2.sql
File metadata and controls
162 lines (133 loc) · 4.45 KB
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
select * from customers;
## 문법 | if(조건, 참일 때 반환 값, 거짓일 때 반환 값)
select
customerName,
customerNumber,
if(creditLimit >= 50000, 'VVIP', 'VIP') as vip_seg
from
customers;
## 문법 | Case when -> 참,거짓 뿐만 아니라 다른 식으로 구분 가능
### high medium low
select
orderNumber,
case
when priceEach >= 100 then 'High'
when priceEach between 30 and 99 then 'Medium'
else 'Low'
end as price_seg
from orderdetails;
## CTE 응용해서 case when 응용하기!
## 해당 조건이면 1, 아니면 0으로 하면 -> case 1 아니면 0 -> 이것을 더하면 내가 원하는 케이스의 카운팅이 된다.
### High 1, 아니면 0 -> High 다 sum 110 내가 원하는 High 카운팅!
select
sum(case when priceEach >= 100 then 1 else 0 end) as cnt_high,
sum(case when priceEach between 30 and 99 then 1 else 0 end) as cnt_medium,
sum(case when priceEach< 30 then 1 else 0 end) as cnt_low
from orderdetails;
# CTE VS 서브쿼리 (자체 이론 정리)
-- (1) 서브쿼리: FROM절 안에 괄호로 넣는 방식 → 읽기 어렵고 중첩이 많아짐
-- (2) CTE : 맨 위에 `WITH … AS`로 이름 붙여두고 재사용 → 훨씬 읽기 쉬움
## CTE 예시
-- WITH cte_name AS (
-- SELECT ... -- 임시로 정의할 쿼리
-- )
-- SELECT ...
-- FROM cte_name;
# 실무의 응용 -> 5월의 구매자, 6월의 구매자, 8월의 구매자 : 코호트 방식
## 코호트 방식 이란, "같은 시점에 시작한 집단이 시간에 따라 어떻게 행동이 달라지는가"를 보려고 하는 것
## 코호트 : 특성이나 경험을 공유하는 집단 (예시 2023년 5월에 첫 구매한 고객 → 5월 코호트)
## (1) Error 상황 : Error Code: 1140. In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'classicmodels.orderdetails.orderNumber'; this is incompatible with sql_mode=only_full_group_by
select
orderNumber,
sum(priceEach* quantityOrdered) as order_total
from
orderdetails
## (2) GROUP BY Error 해결
select
orderNumber,
sum(priceEach* quantityOrdered) as order_total
from
orderdetails
group by
orderNumber;
## (3) JOIN 활용
### orderdetails은 월별 컬럼이 없고 order에는 월별 컬럼 있다 -> JOIN 활용
select *
from orders as o
join
(
select
orderNumber,
sum(priceEach* quantityOrdered) as order_total
from
orderdetails
group by
orderNumber
) as oa
on oa.orderNumber = o.orderNumber
## (4) JOIN으로 만들어진 새로운 표에 서브쿼리 넣기 - 전체 cnt_high/medium/low 수
select
sum(case when order_total >=50000 then 1 else 0 end) as cnt_high,
sum(case when order_total <=10000 and order_total >= 3000 then 1 else 0 end) as cnt_medium, # sum(case when order_total 3000 and 10000 then 1 else 0 end)
sum(case when order_total < 3000 then 1 else 0 end) as cnt_low
from orders as o
join
(
select
orderNumber,
sum(priceEach* quantityOrdered) as order_total
from
orderdetails
group by
orderNumber
) as oa
on oa.orderNumber = o.orderNumber
## (5) GROUP BY - 월별 cnt_high/medium/low 수
### 주문 날짜 기준으로 (연도와 월 기준으로) -> order_total 50000이상이면 High, 5000, 3000 medium, 3000 low
select
date_format(o.orderDate, '%Y-%m') as ym, # GROUP BY 월별
sum(case when order_total >=50000 then 1 else 0 end) as cnt_high,
sum(case when order_total <=10000 and order_total >= 3000 then 1 else 0 end) as cnt_medium, # sum(case when order_total 3000 and 10000 then 1 else 0 end)
sum(case when order_total < 3000 then 1 else 0 end) as cnt_low
from orders as o
join
(
select
orderNumber,
sum(priceEach* quantityOrdered) as order_total
from
orderdetails
group by
orderNumber
) as oa
on oa.orderNumber = o.orderNumber
group by date_format(o.orderDate, '%Y-%m')
order by date_format(o.orderDate, '%Y-%m');
# 날짜 함수의 이론과 실습
with od_8 as (
select
*,
month(orderdate)
from
orders
where
month(orderdate)=8
)
select * from od_8;
## 날짜 계산 관련 함수
## 날짜 계산) 차이 계산 하는 함수 datediff
## 주문 후 -> 요청까지 걸리는 시간
select
orderNumber,
datediff(requiredDate,orderDate) as days_due
from
orders
where datediff(requiredDate, orderDate)>3;
## 예상 배송 기간
## 주문 후에 최소 3일 안에는 우리는 무조건!! 배송이다
select
orderDate,
date_add(orderDate, interval 3 day) as expectedshipment,
shippedDate
from
orders;