ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๐Ÿ’ก ์ƒˆ๋กœ์šด ์ง€ํ‘œ ์ •์˜ํ•˜๊ธฐ

  • ๋ฐ์ดํ„ฐ ์ง‘๊ณ„๋ฅผ ํ†ตํ•ด ์œ ์˜๋ฏธํ•œ ์ง€ํ‘œ๋ฅผ ์ •์˜ํ•˜๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Œ!
  • ๋‹จ์ˆœํ•œ ์ˆซ์ž ๋น„๊ต๋Š” ํฐ ๋ฐ์ดํ„ฐ์—๋งŒ ์ฃผ๋ชฉํ•˜๊ฒŒ ํ•˜์ง€๋งŒ, ‘๊ฐœ์ธ๋ณ„’, ‘๋น„์œจ’ ๊ฐ™์€ ์ง€ํ‘œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ๊ด€์ ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”๋ผ๋ณผ ์ˆ˜ ์žˆ๋‹ค
    ex) <ํŽ˜์ด์ง€ ๋ทฐ> / <๋ฐฉ๋ฌธ์ž ์ˆ˜> : ‘์‚ฌ์šฉ์ž ํ•œ ๋ช…์ด ํŽ˜์ด์ง€๋ฅผ ๋ช‡๋ฒˆ์ด๋‚˜ ๋ฐฉ๋ฌธํ–ˆ๋Š”๊ฐ€?’
    CTR (ํด๋ฆญ๋น„์œจ:Click Through Rate)- ์›น์‚ฌ์ดํŠธ์—์„œ๋Š” ๋ฐฉ๋ฌธํ•œ ์‚ฌ์šฉ์ž ์ˆ˜ ์ค‘์—์„œ ํŠน์ •ํ•œ ํ–‰๋™์„ ์‹œํ–‰ํ•œ ์‚ฌ์šฉ์ž์˜ ๋น„์œจ CVR (์ „ํ™˜์œจ : Conversion Rate ) - ์ „ํ™˜์œจ์€ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ด‘๊ณ ๋ฅผ ๋ณธ ํ›„ ํ–‰๋™์„ '์ „ํ™˜'ํ–ˆ๋Š”์ง€๋ฅผ ์ธก์ •

1. ๋ฌธ์ž์—ด ์—ฐ๊ฒฐํ•˜๊ธฐ

: CONCAT ํ•จ์ˆ˜ or || ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉ

SELECT 
	user_id, CONCAT(pref_name, city_name) AS pref_city, pref_name || city_name AS pref_city2
FROM mst_user_location;

 

  •  

2. ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ’ ๋น„๊ตํ•˜๊ธฐ

: ํ•˜๋‚˜์˜ ๋ ˆ์ฝ”๋“œ์— ํฌํ•จ๋œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ’์„ ๋น„๊ตํ•˜๊ธฐ

4๋ถ„๊ธฐ ๋งค์ถœ ํ…Œ์ด๋ธ”

๋ถ„๊ธฐ๋ณ„ ๋งค์ถœ ์ฆ๊ฐ ํŒ์ •ํ•˜๊ธฐ : 2๊ฐœ์˜ ์ปฌ๋Ÿผ ๋น„๊ต

  • ๋ฐฉ๋ฒ• 1. CASE ๋ฌธ์„ ์ด์šฉํ•ด ๊ฐ ์ปฌ๋Ÿผ์˜ ๋Œ€์†Œ ๋น„๊ต
  • ๋ฐฉ๋ฒ• 2. ๊ฐ’์˜ ์ฐจ์ด ๊ตฌํ•˜๋Š” diff_q2_q1 ๋ณ€์ˆ˜ ์ •์˜ ํ›„, SIGN ํ•จ์ˆ˜ ์ด์šฉ โ€ผ๏ธ SIGN ํ•จ์ˆ˜ → ๋งค๊ฐœ๋ณ€์ˆ˜ ์–‘์ˆ˜๋ฉด 1, 0์ด๋ฉด 0, ์Œ์ˆ˜๋ฉด -1 ๋ฆฌํ„ด
SELECT 
	year, q1, q2,
CASE
	WHEN q1 < q2 THEN '+'
	WHEN q1 = q2 THEN ' '
	ELSE '-'
END AS judge_q1_q2
 , q2-q1 AS diff_q2_q1
, SIGN(q2 - q1) AS sign_q2_q1
FROM quarterly_sales ORDER BY year;

์—ฐ๊ฐ„ ์ตœ๋Œ€/ ์ตœ์†Œ 4๋ถ„๊ธฐ ๋งค์ถœ ์ฐพ๊ธฐ : 3๊ฐœ ์ด์ƒ์˜ ์ปฌ๋Ÿผ ๋น„๊ต

→ greatest(์ปฌ๋Ÿผ1,์ปฌ๋Ÿผ2,..) ํ•จ์ˆ˜ or least(์ปฌ๋Ÿผ1,์ปฌ๋Ÿผ2,...)ํ•จ์ˆ˜

# q1 ~ q4์˜ ์ตœ๋Œ€/์ตœ์†Œ ๋งค์ถœ ๊ตฌํ•˜๊ธฐ
SELECT 
	year, greatest(q1,q2,q3,q4) as greatest_sales,
	least(q1,q2,q3,q4) as least_sales
FROM quarterly_sales ORDER BY year;

์—ฐ๊ฐ„ ํ‰๊ท  4๋ถ„๊ธฐ ๋งค์ถœ ๊ณ„์‚ฐํ•˜๊ธฐ : ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ปฌ๋Ÿผ ์‚ฌ์น™์—ฐ์‚ฐ

# q1 ~ q4์˜ ํ‰๊ท  ๋งค์ถœ ๊ตฌํ•˜๊ธฐ
SELECT 
	year, (q1+q2+q3+q4) / 4 AS average
FROM quarterly_sales ORDER BY year;

2017๋…„์— NULL ๊ฐ’์ด ์žˆ์—ˆ์Œ!

โ€ผ๏ธ ์ด๋•Œ, NULL๊ฐ’ ์‚ฌ์น™ ์—ฐ์‚ฐ ์ฃผ์˜! → COALESCE ํ•จ์ˆ˜ ์ด์šฉํ•ด ๋ณ€ํ™˜ํ•˜๊ธฐ!

# q1 ~ q4์˜ ํ‰๊ท  ๋งค์ถœ ๊ตฌํ•˜๊ธฐ - NULL ์žˆ๋Š” ๊ฒฝ์šฐ
SELECT 
	year, (COALESCE(q1,0) + COALESCE(q2,0) + COALESCE(q3,0) + COALESCE(q4,0)) / 4 AS average
FROM quarterly_sales ORDER BY year;

2017๋…„์—” NULL๊ฐ’์ด ์žˆ๋Š”๋ฐ ์ด๊ฑธ ๋˜‘๊ฐ™์ด 4๋กœ ๋‚˜๋ˆ„๋‹ˆ๊นŒ ํ‰๊ท ๊ฐ’์ด ๋„ˆ๋ฌด ์ž‘์•„์ ธ๋ฒ„๋ฆผ! → 4๋กœ ๋‚˜๋ˆ„์ง€ ๋ง๊ณ  NULL์ด ์•„๋‹Œ ์ปฌ๋Ÿผ์˜ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ด์•ผ ํ•จ!

โ€ผ๏ธ NULL์ด ์•„๋‹Œ ์ปฌ๋Ÿผ ์ˆ˜๋กœ ๋‚˜๋ˆ„๊ธฐ! →SIGN ํ•จ์ˆ˜์™€ COALESCE ํ•จ์ˆ˜ ์กฐํ•ฉ

# q1 ~ q4์˜ ํ‰๊ท  ๋งค์ถœ ๊ตฌํ•˜๊ธฐ - NULL ์žˆ๋Š” ๊ฒฝ์šฐ
# SIGN(COALESCE(q1,0)) : q1์ด NULL ์•„๋‹ˆ๋ฉด +1, q1์ด NULL์ด๋ฉด +0
SELECT year, 
(COALESCE(q1,0) + COALESCE(q2,0) + COALESCE(q3,0) + COALESCE(q4,0)) / (SIGN(COALESCE(q1,0)) + SIGN(COALESCE(q2,0)) + SIGN(COALESCE(q3,0)) + SIGN(COALESCE(q4,0))) AS average
FROM quarterly_sales ORDER BY year;

3. 2๊ฐœ์˜ ๊ฐ’ ๋น„์œจ ๊ณ„์‚ฐํ•˜๊ธฐ

โ€ผ๏ธ ๋น„์œจ ๊ตฌํ•  ๋•Œ๋Š”, ์ •์ˆ˜๋กœ ๋‚˜๋ˆ„๊ฑฐ๋‚˜ 0์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฑฐ ์กฐ์‹ฌํ•  ๊ฒƒ!

๋งค์ผ์˜ ๊ด‘๊ณ  ๋…ธ์ถœ ์ˆ˜ ์™€ ํด๋ฆญ ์ˆ˜ ์ง‘๊ณ„

์ •์ˆ˜ ์ž๋ฃŒํ˜•์˜ ๋ฐ์ดํ„ฐ ๋‚˜๋ˆ„๊ธฐ

  • CTR ๊ณ„์‚ฐ : ํด๋ฆญ ์ˆ˜ / ๋…ธ์ถœ ์ˆ˜
    • ์ •์ˆ˜ ์ž๋ฃŒํ˜•์„ ๋‚˜๋ˆ„๋ฉด, ๊ณ„์‚ฐ ๊ฒฐ๊ณผ ๋˜ํ•œ ์ •์ˆ˜ํ˜•์œผ๋กœ ๋‚˜์˜ค๋ฏ€๋กœ 0์„ ๋ฐ˜ํ™˜
    → cast ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด clicks๋ฅผ double ์ž๋ฃŒํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๊ณ„์‚ฐ → ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๋„ double ํ˜•์œผ๋กœ ๋‚˜์˜ด!
    • ๊ฒฐ๊ณผ๋ฅผ ํผ์„ผํŠธ๋กœ ๋‚˜ํƒ€๋‚ผ ๋•Œ, ctr ์ปฌ๋Ÿผ ๊ฒฐ๊ณผ์— 100์„ ๊ณฑํ•˜๊ธฐ → 100.0 ์„ ๊ณฑํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ž๋ฃŒํ˜•๋ณ€ํ™˜ ์ผ์–ด๋‚จ!
    # cast ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด double ์ž๋ฃŒํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๊ณ„์‚ฐ
    # ์‹ค์ˆ˜๋ฅผ ์ƒ์ˆ  ์•ž์— ๋‘๊ณ  ๊ณ„์‚ฐํ•˜๋ฉด ์•”๋ฌต์ ์œผ๋กœ ์ž๋ฃŒํ˜• ๋ณ€ํ™˜์ด ์ผ์–ด๋‚จ
    SELECT dt, ad_id, CAST(clicks AS double precision) / impressions AS ctr, 
    100.0 * clicks / impressions AS ctr_percent
    FROM advertising_stats
    WHERE dt = '2017-04-01'
    ORDER BY dt, ad_id;
    

0์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ ํ”ผํ•˜๊ธฐ

2017-04-02์˜ impression 0์ด๋ฏ€๋กœ, 0์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์—†์–ด์„œ error ๋ฐœ์ƒ

๋ฐฉ๋ฒ• 1. CASE ์‹์„ ์ด์šฉํ•ด impressions๊ฐ€ 0์ธ์ง€ ํ™•์ธ

๋ฐฉ๋ฒ• 2. NULL ์ „ํŒŒ๋ฅผ ์‚ฌ์šฉ : NULL์„ ํฌํ•จํ•œ ๋ฐ์ดํ„ฐ์˜ ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๊ฐ€ ๋ชจ๋‘ NULL์ด ๋˜๋Š” SQL ์„ฑ์งˆ

NULLIF() ๋ฅผ ์ด์šฉํ•ด ๋ถ„๋ชจ๊ฐ€ 0์ด๋ฉด NULL๋กœ ๋ณ€ํ™˜ํ•ด์„œ 0์œผ๋กœ ๋‚˜๋ˆ„์ง€ ์•Š๊ฒŒ ํ•˜๊ธฐ!

# 1. CASE ์‹์„ ์ด์šฉํ•ด 0์ธ์ง€ ํ™•์ธ
# 2. NULLIF ์ด์šฉ
SELECT dt, ad_id, 
CASE
	WHEN impressions > 0 THEN 100.0 * clicks / impressions
END AS ctr_as_percent_by_case
, 100.0 * clicks / NULLIF(impressions,0) AS ctr_as_percent_by_null
FROM advertising_stats
ORDER BY dt, ad_id;

4. ๋‘ ๊ฐ’์˜ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐํ•˜๊ธฐ

‘๊ฑฐ๋ฆฌ’ : ํ‰๊ท ๊ณผ ์‹œํ—˜ ์ ์ˆ˜๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋–จ์–ด์ ธ ์žˆ๋Š”์ง€, ์ž‘๋…„ ๋งค์ถœ๊ณผ ์˜ฌํ•ด ๋งค์ถœ์— ์–ด๋Š์ •๋„ ์ฐจ์ด๊ฐ€ ์žˆ๋Š”์ง€.., ํŠน์ • ์‚ฌ์šฉ์ž์™€ ํŠน์ • ์‚ฌ์šฉ์ž์˜ ๊ตฌ๋งค ๊ฒฝํ–ฅ์ด ์–ผ๋งˆ๋‚˜ ๋น„์Šทํ•œ์ง€…

์ˆซ์ž ๋ฐ์ดํ„ฐ์˜ ์ ˆ๋Œ“๊ฐ’, ์ œ๊ณฑ ํ‰๊ท  ์ œ๊ณฑ๊ทผ(RMS) ๊ณ„์‚ฐํ•˜๊ธฐ

x1, x2๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฑฐ๋ฆฌ ๊ตฌํ•˜๊ธฐ → 1์ฐจ์› ๋ฐ์ดํ„ฐ

๋ฐฉ๋ฒ•1. ์ ˆ๋Œ“๊ฐ’ ๊ฑฐ๋ฆฌ → ABS() ํ•จ์ˆ˜ ์‚ฌ์šฉ

๋ฐฉ๋ฒ•2. ์ œ๊ณฑํ‰๊ท ์ œ๊ณฑ๊ทผ ์ด์šฉ → ๋‘ ๊ฐ’์˜ ์ฐจ์ด ์ œ๊ณฑ(POWER() ํ•จ์ˆ˜) ํ•œ ํ›„, ์ œ๊ณฑ๊ทผ(SQRT()ํ•จ์ˆ˜) ์”Œ์šฐ๊ธฐ!

SELECT abs(x1-x2) AS abs, sqrt(power(x1 - x2, 2)) AS rms
FROM location_1d;

๊ฐ’์ด 1์ฐจ์›์ด๋ฉด, ๋‘๊ฐœ ๋ชจ๋‘ ๊ฐ™์€ ๊ฐ’!

XYํ‰๋ฉด ์œ„์— ์žˆ๋Š” ๋‘ ์ ์˜ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐํ•˜๊ธฐ

์ด์ฐจ์› ํ…Œ์ด๋ธ”

์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ → ์ œ๊ณฑ ํ‰๊ท  ์ œ๊ณฑ๊ทผ ์ด์šฉ!

  • PostgreSQL์—๋Š” POINT ์ž๋ฃŒํ˜• ์ด๋ผ๋Š” ์ขŒํ‘œ๋ฅผ ๋‹ค๋ฃจ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ ์žˆ์–ด์„œ, POINT ์ž๋ฃŒํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•œ ํ›„ ๊ฑฐ๋ฆฌ ์—ฐ์‚ฐ์ž ↔ ๋ฅผ ์ด์šฉํ•ด์„œ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ!
SELECT
	sqrt(power(x1-x2, 2) + power(y1-y2,2)) AS dist,
	point(x1,y1) <-> point(x2,y2) AS dist
FROM location_2d;

5. ๋‚ ์งœ,์‹œ๊ฐ„ ๊ณ„์‚ฐํ•˜๊ธฐ

  • ๋‘ ๋‚ ์งœ ๋ฐ์ดํ„ฐ์˜ ์ฐจ์ด ๊ตฌํ•˜๊ฑฐ๋‚˜, 1์‹œ๊ฐ„ ํ›„ ์‹œ๊ฐ„ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•

๋“ฑ๋ก์‹œ๊ฐ„๊ณผ ์ƒ์ผ ํฌํ•จํ•˜๋Š” ๋ฐ์ดํ„ฐ

๋ฏธ๋ž˜ ๋˜๋Š” ๊ณผ๊ฑฐ์˜ ๋‚ ์งœ/์‹œ๊ฐ„์„ ๊ณ„์‚ฐ

  • ํšŒ์› ๋“ฑ๋ก ์‹œ๊ฐ„ 1์‹œ๊ฐ„ ํ›„์™€ 30๋ถ„ ์ „์˜ ์‹œ๊ฐ„, ๋“ฑ๋ก์ผ์˜ ๋‹ค์Œ๋‚ ๊ณผ 1๋‹ฌ ์ „์˜ ๋‚ ์งœ๋ฅผ ๊ณ„์‚ฐ
  • ์ •์ˆ˜์˜ ๋ง์…ˆ๊ณผ ๋บ„์…ˆ ์‚ฌ์šฉ
  • postgresql์˜ ๊ฒฝ์šฐ interval ์ž๋ฃŒํ˜• ์ด์šฉ โ€ผ๏ธ interval ํƒ€์ž…์€ year, month, day, hour, minute, second ๋“ฑ์˜ ๋‹จ์œ„์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ๋‚ ์งœ/์‹œ๊ฐ„ ์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅ
SELECT user_id, register_stamp::timestamp as register_stamp,
register_stamp::timestamp + '1 hour'::interval AS after_1_hour,
register_stamp::timestamp - '30 minutes'::interval AS before_30_minutes,

register_stamp::date as register_date, 
(register_stamp::date + '1 day'::interval)::date as after_1_day,
(register_stamp::date - '1 month'::interval)::date as before_1_month
FROM mst_users_with_dates;

๋‚ ์งœ ๋ฐ์ดํ„ฐ๋“ค์˜ ์ฐจ์ด ๊ณ„์‚ฐํ•˜๊ธฐ

๋‘ ๋‚ ์งœ ๋ฐ์ดํ„ฐ ์ด์šฉํ•ด ๋‚ ์งœ์˜ ์ฐจ์ด ๊ณ„์‚ฐํ•˜๊ธฐ

  • ํšŒ์› ๋“ฑ๋ก์ผ๊ณผ ํ˜„์žฌ ๋‚ ์งœ์˜ ์ฐจ์ด
# PostgreSQL์˜ ๊ฒฝ์šฐ ๋‚ ์งœ ์ž๋ฃŒํ˜• ๋ผ๋ฆฌ ๋บ„ ์ˆ˜ ์žˆ์Œ
SELECT user_id, 
CURRENT_DATE AS today, register_stamp::Date AS register_date,
CURRENT_DATE - register_stamp::date AS diff_days
FROM mst_users_with_dates;

์‚ฌ์šฉ์ž์˜ ์ƒ๋…„์›”์ผ๋กœ ๋‚˜์ด ๊ณ„์‚ฐํ•˜๊ธฐ

๋‚ ์งœ ์ฐจ์ด ๊ตฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋‚˜์ด ๊ณ„์‚ฐ์€ ์กฐ๊ธˆ ๋ณต์žก → ๋‹จ์ˆœํ•˜๊ฒŒ 365์ผ๋กœ ๋‚˜๋ˆ„๋ฉด ๋˜๋Š” ๊ฒŒ ์•„๋‹˜! ์œค๋…„๋„ ๊ณ ๋ คํ•ด์•ผ ํ•จ!

๋ฐฉ๋ฒ•1. PostgreSQL์—๋Š” ๋‚˜์ด ๊ณ„์‚ฐ ์ „์šฉํ•จ์ˆ˜๊ฐ€ ๊ตฌํ˜„ ๋˜์–ด ์žˆ์Œ! AGE() ํ•จ์ˆ˜

# EXTRACTํ•จ์ˆ˜๋กœ ์—ฐ๋„ ๋ถ€๋ถ„๋งŒ์„ ์ถ”์ถœ
SELECT user_id,
CURRENT_DATE AS today, register_stamp::date AS register_date,
birth_date::date AS birth_date,
EXTRACT(YEAR FROM age(birth_date::date)) AS current_age,
EXTRACT(YEAR FROM age(register_stamp::date, birth_date::date)) AS register_age
FROM mst_users_with_dates;

cf) EXTRACT() ์•ˆ ์จ์ฃผ๋ฉด, interval ์ž๋ฃŒํ˜•์˜ ๋‚ ์งœ ๋‹จ์œ„ ์ถœ๋ ฅ๋จ → EXTRACT๋กœ ์—ฐ๋„๋งŒ ์ถ”์ถœ!

๋ฐฉ๋ฒ•2. ๋‚ ์งœ๋ฅผ ์ •์ˆ˜๋กœ ํ‘œํ˜„ํ•ด์„œ ๋นผ์ค€ ํ›„, 10,000์œผ๋กœ ๋‚˜๋ˆ ์ฃผ๊ธฐ

  • ๋‚ ์งœ๋ฅผ ๊ณ ์ • ์ž๋ฆฌ ์ˆ˜์˜ ์ •์ˆ˜๋กœ ํ‘œํ˜„!
# 2000๋…„ 2์›” 29์ผ์ธ ์‚ฌ๋žŒ 2016๋…„ 2์›” 28์ผ ์‹œ์ ์˜ ๋‚˜์ด ๊ณ„์‚ฐ
SELECT floor((20160228 - 20000229) / 10000) AS age;

๋ฐฉ๋ฒ•3. ๋ฌธ์ž์—ด๋กœ ๊ณ„์‚ฐํ•˜๊ธฐ

  • ๋ฌธ์ž์—ด์—์„œ ํ•˜์ดํ”ˆ์„ ์ œ๊ฑฐํ•˜๊ณ , ์ •์ˆ˜๋กœ ์บ์ŠคํŠธ!
SELECT user_id,
substring(register_stamp,1,10) AS register_date, birth_date,
-- ๋“ฑ๋ก ์‹œ์ ์˜ ๋‚˜์ด ๊ณ„์‚ฐ
floor((CAST(replace(substring(register_stamp, 1, 10),'-','') AS integer) - 
CAST(replace(birth_date, '-','') AS integer)
)/ 10000) AS register_age,
-- ํ˜„์žฌ ์‹œ์ ์˜ ๋‚˜์ด ๊ณ„์‚ฐ
floor((CAST(replace(CAST(CURRENT_DATE AS text),'-','') AS integer) - 
CAST(replace(birth_date, '-','') AS integer)
)/ 10000) AS current_age
FROM mst_users_with_dates;

6. IP ์ฃผ์†Œ ์ž๋ฃŒํ˜• ํ™œ์šฉํ•˜๊ธฐ

  • IP ์ฃผ์†Œ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ inet ์ž๋ฃŒํ˜• ๊ตฌํ˜„๋˜์–ด ์žˆ์Œ!
  • inet ์ž๋ฃŒํ˜•์„ ํ†ตํ•ด IP ์ฃผ์†Œ ์‰ฝ๊ฒŒ ๋น„๊ต ๊ฐ€๋Šฅ ! <, >
SELECT
CAST('127.0.0.1' AS inet) < CAST('127.0.0.2' AS inet) AS lt,
CAST('127.0.0.1' AS inet) > CAST('127.0.0.2' AS inet) AS gt;

→ ์กฐ๊ฑด์— ํ•ด๋‹นํ• ๊ฒฝ์šฐ t, ์•„๋‹ ๊ฒฝ์šฐ f ๋ฆฌํ„ด

  • address/y ํ˜•ํƒœ์˜ ๋„คํŠธ์›Œํฌ ๋ฒ”์œ„์— IP ์ฃผ์†Œ ํฌํ•จ ์—ฌ๋ถ€ ํŒ์ • ๊ฐ€๋Šฅ<< ๋˜๋Š” >> ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ
SELECT
  CAST('127.0.0.1' AS inet) << CAST('127.0.0.0/8' AS inet) AS is_contained;

์ •์ˆ˜ ๋˜๋Š” ๋ฌธ์ž์—ด๋กœ IP ๋‹ค๋ฃจ๊ธฐ

  • inet ์ž๋ฃŒํ˜•์ฒ˜๋Ÿผ ์•ˆ๋  ๊ฒฝ์šฐ! → ์ •์ˆ˜ or ๋ฌธ์ž์—ด๋กœ IP ๋‹ค๋ฃจ๊ธฐ
  • split_part() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋ฌธ์ž์—ด ๋ถ„ํ•ดํ•œ ํ›„, ์ •์ˆ˜ํ˜•์œผ๋กœ ๋ฐ”๊พธ๊ธฐ!
SELECT
  ip
  , CAST(split_part(ip, '.', 1) AS integer) AS ip_part_1
  , CAST(split_part(ip, '.', 2) AS integer) AS ip_part_2
  , CAST(split_part(ip, '.', 3) AS integer) AS ip_part_3
  , CAST(split_part(ip, '.', 4) AS integer) AS ip_part_4
FROM
  (SELECT CAST('192.168.0.1' AS text) AS ip) AS t;

  • ์ถ”์ถœํ•œ 4๊ฐœ์˜ 10์ง„์ˆ˜ ๋ถ€๋ถ„์„ 2^24, 2^16, 2^8, 2^0์œผ๋กœ ๊ณฑํ•˜๊ณ  ๋”ํ•˜๋ฉด ์ •์ˆ˜ํ˜• ์ž๋ฃŒํ˜• ํ‘œ๊ธฐ๋กœ ๋ณ€ํ™˜ → ๋Œ€์†Œ ๋น„๊ต ๋ฐ ๋ฒ”์œ„ ํŒ์ •์ด ๊ฐ€๋Šฅ
SELECT
  ip
  , CAST(split_part(ip, '.', 1) AS integer) * 2^24
    + CAST(split_part(ip, '.', 2) AS integer) * 2^16
    + CAST(split_part(ip, '.', 3) AS integer) * 2^8
    + CAST(split_part(ip, '.', 4) AS integer) * 2^0
  AS ip_integer FROM (SELECT CAST('192.168.0.1' AS text) AS ip) AS t;

  • IP ์ฃผ์†Œ๋ฅผ 0์œผ๋กœ ๋ฉ”์šฐ๊ธฐ→ lpadํ•จ์ˆ˜๋ฅผ ์ด์šฉ! : ์ง€์ •ํ•œ ๋ฌธ์ž ์ˆ˜๊ฐ€ ๋˜๊ฒŒ ๋ฌธ์ž์—ด์˜ ์™ผ์ชฝ์„ ๋ฉ”์›€!
    • ๋ฐ์ดํ„ฐ ์ง‘๊ณ„๋ฅผ ํ†ตํ•ด ์œ ์˜๋ฏธํ•œ ์ง€ํ‘œ๋ฅผ ์ •์˜ํ•˜๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Œ!
    • ๋‹จ์ˆœํ•œ ์ˆซ์ž ๋น„๊ต๋Š” ํฐ ๋ฐ์ดํ„ฐ์—๋งŒ ์ฃผ๋ชฉํ•˜๊ฒŒ ํ•˜์ง€๋งŒ, ‘๊ฐœ์ธ๋ณ„’, ‘๋น„์œจ’ ๊ฐ™์€ ์ง€ํ‘œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ๊ด€์ ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”๋ผ๋ณผ ์ˆ˜ ์žˆ๋‹ค
SELECT
  ip
  , lpad(split_part(ip, '.', 1), 3, '0')
    || lpad(split_part(ip, '.', 2), 3, '0')
    || lpad(split_part(ip, '.', 3), 3, '0')
    || lpad(split_part(ip, '.', 4), 3, '0')
  AS ip_padding FROM (SELECT CAST('192.168.0.1' AS text) AS ip) AS t;

๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
ยซ   2024/07   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
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
๊ธ€ ๋ณด๊ด€ํ•จ