๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
SQL/SQL ๋ ˆ๋ฒจ์—…

[SQL ๋ ˆ๋ฒจ์—…] 3์žฅ: SQL์˜ ์กฐ๊ฑด ๋ถ„๊ธฐ

by oliviarla 2022. 4. 11.

UNION์„ ์‚ฌ์šฉํ•œ ๊ธด ํ‘œํ˜„

UNION์„ ์‚ฌ์šฉํ•œ ์กฐ๊ฑด ๋ถ„๊ธฐ๋Š” ์ƒ๊ฐํ•˜๊ธฐ ์‰ฝ์ง€๋งŒ ์„ฑ๋Šฅ์ ์ธ ์ธก๋ฉด์—์„œ ๋ณด๋ฉด SELECT๋ฌธ์„ ์—ฌ๋Ÿฌ๊ฐœ ์‹คํ–‰ํ•˜์—ฌ ํ…Œ์ด๋ธ” ์ ‘๊ทผ ํšŸ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ -> I/O๋น„์šฉ ์ฆ๊ฐ€

1. UNION ์‚ฌ์šฉํ•œ ์กฐ๊ฑด ๋ถ„๊ธฐ ์˜ˆ์ œ

SELECT Item_name, year, price_tax_ex AS price
    FROM Items
    WHERE year <=2001
UNION ALL
SELECT Item_name, year, price_tax_in AS price
    FROM Items
    WHERE year > 2001;

๊ฑฐ์˜ ๊ฐ™์€ ์ฟผ๋ฆฌ๋ฅผ ๋‘๋ฒˆ ์‹คํ–‰ํ•˜์—ฌ ๊ฐ€๋…์„ฑ ์ €ํ•˜

Items ํ…Œ์ด๋ธ”์— 2ํšŒ ์ ‘๊ทผํ•˜์—ฌ ์„ฑ๋Šฅ ์ €ํ•˜

-> ์ •ํ™•ํ•œ ํŒ๋‹จ ์—†์ด UNION ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ž์ œํ•˜์ž

2. SELECT ๊ตฌ๋ฅผ ์‚ฌ์šฉํ•œ ์กฐ๊ฑด ๋ถ„๊ธฐ ์˜ˆ์ œ

SELECT item_name, year,
    CASE WHEN year<=2001 THEN price_tax_ex,
         WHEN year<=2001 THEN price_tax_in END AS price
    FROM Items;

ํ…Œ์ด๋ธ”์— 1ํšŒ๋งŒ ์ ‘๊ทผํ•˜์—ฌ ์„ฑ๋Šฅ ๊ฐœ์„ 

์ง‘๊ณ„์™€ ์กฐ๊ฑด ๋ถ„๊ธฐ

1. ์ง‘๊ณ„ ๋Œ€์ƒ์œผ๋กœ ์กฐ๊ฑด ๋ถ„๊ธฐ

์ง€์—ญ ์ด๋ฆ„(location) ์„ฑ๋ณ„(sex) ์ธ๊ตฌ(pop)

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑ๋œ ํ…Œ์ด๋ธ”๋กœ๋ถ€ํ„ฐ

์ง€์—ญ ์ด๋ฆ„(location) ๋‚จ์„ฑ ์ธ๊ตฌ ์—ฌ์„ฑ ์ธ๊ตฌ

์œ„์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•œ ๊ตฌ๋ฌธ ์ƒ์„ฑ

 

- UNION ์‚ฌ์šฉ

๋‚จ์„ฑ ์ธ๊ตฌ๋ฅผ ์ง€์—ญ๋ณ„๋กœ ๊ตฌํ•˜๊ณ  ์—ฌ์„ฑ ์ธ๊ตฌ๋ฅผ ์ง€์—ญ๋ณ„๋กœ ๊ตฌํ•œ ํ›„ merge

SELECT location, SUM(pop_m) AS pop_m, SUM(pop_fm) AS pop_wom
    FROM (SELECT location, pop AS pop_m, null AS pop_fm
          FROM Population
          WHERE sex='1'
          UNION
          SELECT location, NULL AS pop_fm, pop AS pop_fm
          WHERE sex='2') TMP
    GROUP BY location;

Seq Scan 2ํšŒ ์ˆ˜ํ–‰

- CASE ์‚ฌ์šฉ

SELECT location,
    SUM(CASE WHEN sex='1' THEN pop ELSE 0 END) AS pop_m,
    SUM(CASE WHEN sex='2' THEN pop ELSE 0 END AS pop_fm
    FROM Population
    GROUP BY location;

Seq Scan 1ํšŒ ์ˆ˜ํ–‰

2. ์ง‘์•ฝ ๊ฒฐ๊ณผ๋กœ ์กฐ๊ฑด ๋ถ„๊ธฐ

์†Œ์†๋œ ํŒ€์˜ ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฟผ๋ฆฌ ์ž‘์„ฑํ•˜๊ธฐ

- UNION ์‚ฌ์šฉ

SELECT emp_name, MAX(team) AS team
    FROM Employees
    GROUP BY emp_name
    HAVING count(*)=1
UNION
SELECT emp_name, '2๊ฐœ๋ฅผ ๊ฒธ๋ฌด' AS team
    FROM Employees
    GROUP BY emp_name
    HAVING count(*)=2
UNION
SELECT emp_name, '3๊ฐœ ์ด์ƒ์„ ๊ฒธ๋ฌด' AS team
    FROM Employees
    GROUP BY emp_name
    HAVING count(*)>=3;

3๋ฒˆ์˜ TABLE ACCESS FULL ๋ฐœ์ƒ

emp_name์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•œ ์ง‘ํ•ฉ์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๋ฏ€๋กœ HAVING ๊ตฌ ์‚ฌ์šฉ

- CASE ์‹ ์‚ฌ์šฉ

SELECT emp_name,
    CASE WHEN COUNT(*)=1 THEN MAX(team)
         WHEN COUNT(*)=2 THEN '2๊ฐœ๋ฅผ ๊ฒธ๋ฌด'
         WHEN COUNT(*)=3 THEN '3๊ฐœ ์ด์ƒ์„ ๊ฒธ๋ฌด'
         END AS team
    FROM Employees
    GROUP BY emp_name;

UNION์ด ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ

1. UNION์„ ์‚ฌ์šฉํ•  ์ˆ˜๋ฐ–์— ์—†๋Š” ๊ฒฝ์šฐ

์—ฌ๋Ÿฌ ๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์—์„œ ๊ฒ€์ƒ‰ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋จธ์ง€ํ•˜๋Š” ๊ฒฝ์šฐ

SELECT col_1
    FROM Table_A
    WHERE col_2='A'
UNION
SELECT col_3
    FROM Table_B
    WHERE col_4='B'

2. UNION์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์„ฑ๋Šฅ์ ์œผ๋กœ ์ข‹์€ ๊ฒฝ์šฐ

์ธ๋ฑ์Šค์™€ ๊ด€๋ จ๋œ ๊ฒฝ์šฐ

ํ…Œ์ด๋ธ”์˜ ํฌ๊ธฐ๊ฐ€ ์ปค TABLE FULL SCAN๋ณด๋‹ค INDEX RANGE SCAN์ด ํšจ์œจ์ ์ผ ๊ฒฝ์šฐ ์ธ๋ฑ์Šค์™€ UNION ์กฐํ•ฉ์ด ๋” ์„ฑ๋Šฅ์ด ์ข‹์„ ์ˆ˜ ์žˆ๋‹ค

OR, IN ์‚ฌ์šฉ ์‹œ WHERE๊ตฌ๋ฌธ์—์„œ ํ•ด๋‹น ํ•„๋“œ์— ๋ถ€์—ฌ๋œ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ -> ํ…Œ์ด๋ธ”์ด ํฌ๊ณ  WHERE ์กฐ๊ฑด์œผ๋กœ ์„ ํƒ๋˜๋Š” ๋ ˆ์ฝ”๋“œ ์ˆ˜๊ฐ€ ์ถฉ๋ถ„ํžˆ ์ž‘๋‹ค๋ฉด UNION์ด ๋” ๋น ๋ฆ„ 

์ ˆ์ฐจ ์ง€ํ–ฅํ˜•๊ณผ ์„ ์–ธํ˜•

์กฐ๊ฑด ๋ถ„๊ธฐ๋Š” ์กฐ๊ฑด ๋ถ„๊ธฐ๋ฅผ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ CASE ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด UNION์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ข‹์Œ

SQL ๊ตฌ๋ฌธ ๋‚ด๋ถ€์—๋Š” ์‹(expression)์„ ์ž‘์„ฑ -> ์„ ์–ธ์ ์ธ ์‹์— ์ ์‘ ํ•„์š”

๋Œ“๊ธ€