DATE() / DATETIME() / TIMESTAMP() / TIME()
TIMESTAMP()에서는 시간대 설정 가능 (참고. 한국 시간대 : ‘Asia/Seoul’)
SELECT
order_purchase_timestamp,
DATE(order_purchase_timestamp) ord_date,
DATETIME(order_purchase_timestamp) ord_dt,
TIMESTAMP(order_purchase_timestamp) ord_ts,
TIMESTAMP(DATE(order_purchase_timestamp)) ord_date_ts,
TIME(order_purchase_timestamp) ord_time
FROM `olist.olist_orders`
;

- 날짜에서 일부분만 추출하고 싶을 때
- EXTRACT(‘추출할 부분’ FROM ‘날짜 컬럼’)

SELECT
order_purchase_timestamp,
EXTRACT(YEAR FROM order_purchase_timestamp) AS YEAR,
EXTRACT(QUARTER FROM order_purchase_timestamp) AS QUARTER,
EXTRACT(MONTH FROM order_purchase_timestamp) AS MONTH,
EXTRACT(DAY FROM order_purchase_timestamp) AS DAY,
EXTRACT(DAYOFWEEK FROM order_purchase_timestamp) AS DAYOFWEEK,
EXTRACT(WEEK FROM order_purchase_timestamp) AS WEEK,
EXTRACT(WEEK(MONDAY) FROM order_purchase_timestamp) AS WEEK_MONDAY,
EXTRACT(HOUR FROM order_purchase_timestamp) AS HOUR,
EXTRACT(MINUTE FROM order_purchase_timestamp) AS MINUTE,
EXTRACT(SECOND FROM order_purchase_timestamp) AS SECOND
FROM
`olist.olist_orders`
WHERE
DATE(order_purchase_timestamp) = '2017-11-26'
;

TRUNC
- DATE_TRUNC(‘날짜’, ‘남기는 부분’)
- DATETIME_TRUNC(‘날짜’, ‘남기는 부분’)
- TIMESTAMP_TRUNC(‘날짜’, ‘남기는 부분’)

SELECT
order_purchase_timestamp,
TIMESTAMP_TRUNC(order_purchase_timestamp, YEAR) AS YEAR,
TIMESTAMP_TRUNC(order_purchase_timestamp, QUARTER) AS QUARTER,
TIMESTAMP_TRUNC(order_purchase_timestamp, MONTH) AS MONTH,
TIMESTAMP_TRUNC(order_purchase_timestamp, DAY) AS DAY,
TIMESTAMP_TRUNC(order_purchase_timestamp, WEEK) AS WEEK,
TIMESTAMP_TRUNC(order_purchase_timestamp, WEEK(MONDAY)) AS WEEK_MONDAY,
TIMESTAMP_TRUNC(order_purchase_timestamp, HOUR) AS HOUR,
TIMESTAMP_TRUNC(order_purchase_timestamp, MINUTE) AS MINUTE,
TIMESTAMP_TRUNC(order_purchase_timestamp, SECOND) AS SECOND
FROM `olist.olist_orders`
WHERE
DATE(order_purchase_timestamp) = '2017-11-26'
;

SELECT
order_purchase_timestamp,
EXTRACT(YEAR FROM order_purchase_timestamp) AS YEAR,
TIMESTAMP_TRUNC(order_purchase_timestamp, YEAR) AS YEAR2,
EXTRACT(MONTH FROM order_purchase_timestamp) AS MONTH,
TIMESTAMP_TRUNC(order_purchase_timestamp, MONTH) AS MONTH2
FROM `olist.olist_orders`
WHERE
DATE(order_purchase_timestamp) = '2017-11-26'
;

종합쿼리에 날짜추가
- 주문당 정보를 나타내는 테이블 만드는 쿼리에 날짜추가
WITH tb AS (
SELECT
item.order_id,
SUM(item.price) AS ord_amt,
COUNT(DISTINCT item.order_item_id) AS prd_cnt
FROM `olist.olist_order_items` AS item
GROUP BY item.order_id
)
, base AS (
SELECT
ord.order_approved_at,
DATE(ord.order_approved_at) as ord_date,
DATETIME(ord.order_approved_at) as ord_dt,
TIMESTAMP(ord.order_approved_at) as ord_ts,
EXTRACT(YEAR FROM ord.order_approved_at) as ord_year,
EXTRACT(MONTH FROM ord.order_approved_at) as ord_month,
TIMESTAMP_TRUNC(ord.order_approved_at, YEAR) as ord_year_t,
TIMESTAMP_TRUNC(ord.order_approved_at, MONTH) as ord_month_t,
ord.order_id,
ord.order_status,
ord.customer_id,
cust.customer_unique_id,
tb.ord_amt,
tb.prd_cnt
FROM `olist.olist_orders` ord
LEFT JOIN `olist.olist_customers` cust
ON ord.customer_id = cust.customer_id
INNER JOIN tb
ON ord.order_id = tb.order_id
)
SELECT
ord_month_t,
SUM(ord_amt) AS `총매출`,
COUNT(DISTINCT order_id) `총주문수`,
SUM(prd_cnt) `총판매상품수`,
SUM(ord_amt) / COUNT(DISTINCT order_id) `주문당평균가격`,
SUM(prd_cnt) / COUNT(DISTINCT order_id) `평균판매상품수`,
SUM(ord_amt) / SUM(prd_cnt) `제품개당평균가격`,
COUNT(DISTINCT customer_unique_id) `주문고객수`,
COUNT(DISTINCT order_id) / COUNT(DISTINCT customer_unique_id) `주문빈도`
FROM base
GROUP BY ord_month_t
ORDER BY ord_month_t
;

GROUP BY 했을 때 NULL값이 있는 이유 : olist_orders 원본에서 일부 행의 날짜가 NULL값이기 때문!