forked from anthonydb/practical-sql-2
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathChapter_12.sql
241 lines (186 loc) · 7.13 KB
/
Chapter_12.sql
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
---------------------------------------------------------------------------
-- 실용 SQL
-- by Anthony DeBarros
----------------------------------------------------------------------------
-- 코드 12-1: date_part()를 사용하여 timestamp 값의 구성 요소 추출하기
SELECT
date_part('year', '2022-12-01 18:37:12 EST'::timestamptz) AS year,
date_part('month', '2022-12-01 18:37:12 EST'::timestamptz) AS month,
date_part('day', '2022-12-01 18:37:12 EST'::timestamptz) AS day,
date_part('hour', '2022-12-01 18:37:12 EST'::timestamptz) AS hour,
date_part('minute', '2022-12-01 18:37:12 EST'::timestamptz) AS minute,
date_part('seconds', '2022-12-01 18:37:12 EST'::timestamptz) AS seconds,
date_part('timezone_hour', '2022-12-01 18:37:12 EST'::timestamptz) AS tz,
date_part('week', '2022-12-01 18:37:12 EST'::timestamptz) AS week,
date_part('quarter', '2022-12-01 18:37:12 EST'::timestamptz) AS quarter,
date_part('epoch', '2022-12-01 18:37:12 EST'::timestamptz) AS epoch;
-- 보너스: 표준 SQL extract()을 사용한 datetime 파싱
SELECT extract(year from '2022-12-01 18:37:12 EST'::timestamptz) AS year;
-- 코드 12-2: 요소에서 datetime을 만드는 세 가지 함수
-- 날짜 만들기
SELECT make_date(2022, 2, 22);
-- 시간 만들기
SELECT make_time(18, 4, 30.3);
-- 시간대가 적용된 timestamp 만들기
SELECT make_timestamptz(2022, 2, 22, 18, 4, 30.3, 'Europe/Lisbon');
-- 보너스: 현재 날짜와 시간 받아오기
SELECT
current_timestamp,
localtimestamp,
current_date,
current_time,
localtime,
now();
-- 코드 12-3: 행 삽입 중 current_timestamp와 clock_timestamp() 비교하기
CREATE TABLE current_time_example (
time_id integer GENERATED ALWAYS AS IDENTITY,
current_timestamp_col timestamptz,
clock_timestamp_col timestamptz
);
INSERT INTO current_time_example
(current_timestamp_col, clock_timestamp_col)
(SELECT current_timestamp,
clock_timestamp()
FROM generate_series(1,1000));
SELECT * FROM current_time_example;
-- 시간대
-- 코드 12-4: 현재 시간대 확인하기
SHOW timezone; -- 참고: SHOW ALL을 사용하면 모든 런타임 설정을 확인할 수 있습니다;
SELECT current_setting('timezone');
-- 다른 함수 입력에는 current_setting() 사용하기:
SELECT make_timestamptz(2022, 2, 22, 18, 4, 30.3, current_setting('timezone'));
-- 코드 12-5: 시간대 약어와 이름 보이기
SELECT * FROM pg_timezone_abbrevs ORDER BY abbrev;
SELECT * FROM pg_timezone_names ORDER BY name;
-- 필터를 적용해 한 가지 약어 찾기
SELECT * FROM pg_timezone_names
WHERE name LIKE 'Europe%'
ORDER BY name;
-- 코드 12-6: 클라이언트 세션의 시간대 설정하기
SET TIME ZONE 'US/Pacific';
CREATE TABLE time_zone_test (
test_date timestamptz
);
INSERT INTO time_zone_test VALUES ('2023-01-01 4:00');
SELECT test_date
FROM time_zone_test;
SET TIME ZONE 'US/Eastern';
SELECT test_date
FROM time_zone_test;
SELECT test_date AT TIME ZONE 'Asia/Seoul'
FROM time_zone_test;
-- 날짜 계산하기!
SELECT '1929-09-30'::date - '1929-09-27'::date;
SELECT '1929-09-30'::date + '5 years'::interval;
-- 택시 데이터
-- 코드 12-7: 테이블 생성 및 뉴욕시의 노란색 택시 데이터 가져오기
CREATE TABLE nyc_yellow_taxi_trips (
trip_id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
vendor_id text NOT NULL,
tpep_pickup_datetime timestamptz NOT NULL,
tpep_dropoff_datetime timestamptz NOT NULL,
passenger_count integer NOT NULL,
trip_distance numeric(8,2) NOT NULL,
pickup_longitude numeric(18,15) NOT NULL,
pickup_latitude numeric(18,15) NOT NULL,
rate_code_id text NOT NULL,
store_and_fwd_flag text NOT NULL,
dropoff_longitude numeric(18,15) NOT NULL,
dropoff_latitude numeric(18,15) NOT NULL,
payment_type text NOT NULL,
fare_amount numeric(9,2) NOT NULL,
extra numeric(9,2) NOT NULL,
mta_tax numeric(5,2) NOT NULL,
tip_amount numeric(9,2) NOT NULL,
tolls_amount numeric(9,2) NOT NULL,
improvement_surcharge numeric(9,2) NOT NULL,
total_amount numeric(9,2) NOT NULL
);
COPY nyc_yellow_taxi_trips (
vendor_id,
tpep_pickup_datetime,
tpep_dropoff_datetime,
passenger_count,
trip_distance,
pickup_longitude,
pickup_latitude,
rate_code_id,
store_and_fwd_flag,
dropoff_longitude,
dropoff_latitude,
payment_type,
fare_amount,
extra,
mta_tax,
tip_amount,
tolls_amount,
improvement_surcharge,
total_amount
)
FROM 'C:\YourDirectory\nyc_yellow_taxi_trips.csv'
WITH (FORMAT CSV, HEADER);
CREATE INDEX tpep_pickup_idx
ON nyc_yellow_taxi_trips (tpep_pickup_datetime);
-- 전체 데이터 세기
SELECT count(*) FROM nyc_yellow_taxi_trips;
-- 코드 12-8: 시간별 택시 운행 횟수 계산하기
SET TIME ZONE 'US/Eastern';
SELECT
date_part('hour', tpep_pickup_datetime) AS trip_hour,
count(*)
FROM nyc_yellow_taxi_trips
GROUP BY trip_hour
ORDER BY trip_hour;
-- 코드 12-9: 시간당 택시 승차 숫자를 CSV 파일로 내보내기
COPY
(SELECT
date_part('hour', tpep_pickup_datetime) AS trip_hour,
count(*)
FROM nyc_yellow_taxi_trips
GROUP BY trip_hour
ORDER BY trip_hour
)
TO 'C:\YourDirectory\hourly_taxi_pickups.csv'
WITH (FORMAT CSV, HEADER);
-- 코드 12-10: 시간별 이동 시간 중앙값 계산하기
SELECT
date_part('hour', tpep_pickup_datetime) AS trip_hour,
percentile_cont(.5)
WITHIN GROUP (ORDER BY
tpep_dropoff_datetime - tpep_pickup_datetime) AS median_trip
FROM nyc_yellow_taxi_trips
GROUP BY trip_hour
ORDER BY trip_hour;
-- 코드 12-11: 기차 이동 데이터를 보관할 테이블 만들기
CREATE TABLE train_rides (
trip_id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
segment text NOT NULL,
departure timestamptz NOT NULL,
arrival timestamptz NOT NULL
);
INSERT INTO train_rides (segment, departure, arrival)
VALUES
('Chicago to New York', '2020-11-13 21:30 CST', '2020-11-14 18:23 EST'),
('New York to New Orleans', '2020-11-15 14:15 EST', '2020-11-16 19:32 CST'),
('New Orleans to Los Angeles', '2020-11-17 13:45 CST', '2020-11-18 9:00 PST'),
('Los Angeles to San Francisco', '2020-11-19 10:10 PST', '2020-11-19 21:24 PST'),
('San Francisco to Denver', '2020-11-20 9:10 PST', '2020-11-21 18:38 MST'),
('Denver to Chicago', '2020-11-22 19:10 MST', '2020-11-23 14:50 CST');
SET TIME ZONE 'US/Central';
SELECT * FROM train_rides;
-- 코드 12-12: 각 이동 구간의 길이 계산하기
SELECT segment,
to_char(departure, 'YYYY-MM-DD HH12:MI a.m. TZ') AS departure,
arrival - departure AS segment_duration
FROM train_rides;
-- 코드 12-13: OVER를 사용하여 누적 간격 계산하기
SELECT segment,
arrival - departure AS segment_duration,
sum(arrival - departure) OVER (ORDER BY trip_id) AS cume_duration
FROM train_rides;
-- 코드 12-14: justify_interval()을 사용한 누적 여행 기간 형식화
SELECT segment,
arrival - departure AS segment_duration,
justify_interval(sum(arrival - departure)
OVER (ORDER BY trip_id)) AS cume_duration
FROM train_rides;