๐Ÿ“ŒSQL ์กฐ์ธ(SQL JOIN) ๊ฐœ๋…, ํ™œ์šฉ, ์ตœ์ 

๊น€๋™ํ˜ยท2025๋…„ 1์›” 21์ผ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

๋ชฉ๋ก ๋ณด๊ธฐ
2/2


ํ™”

SQL ์กฐ์ธ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•˜์—ฌ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ํ•„์ˆ˜์ ์ธ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.
์ด ๊ธ€์—์„œ๋Š” ๊ฐ ์กฐ์ธ์˜ ๊ฐœ๋…, ์ฐจ์ด์ , ์‚ฌ์šฉ ์‚ฌ๋ก€, ํผํฌ๋จผ์Šค ์ตœ์ ํ™” ๋ฐฉ๋ฒ•๊นŒ์ง€ ์ฒด๊ณ„์ ์œผ๋กœ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ”น SQL ์กฐ์ธ์˜ ์ข…๋ฅ˜ ๋ฐ ๊ฐœ๋…

SQL ์กฐ์ธ์€ ํฌ๊ฒŒ INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN, UNION, INTERSECT๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.
๊ฐ ์กฐ์ธ์˜ ๊ฐœ๋…๊ณผ ์ฐจ์ด์ ์„ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์กฐ์ธ ์ข…๋ฅ˜์„ค๋ช…๋น„์œ SQL ๋ฌธ๋ฒ•
INNER JOIN๊ณตํ†ต๋œ ๋ฐ์ดํ„ฐ๋งŒ ๋ฐ˜ํ™˜๋‘ ํ…Œ์ด๋ธ”์—์„œ ๊ฒน์น˜๋Š” ๋ถ€๋ถ„๋งŒ ์ถ”์ถœINNER JOIN
LEFT JOIN์™ผ์ชฝ ํ…Œ์ด๋ธ” ๋ชจ๋“  ๋ฐ์ดํ„ฐ + ์˜ค๋ฅธ์ชฝ ๋งค์นญ ๋ฐ์ดํ„ฐ์™ผ์ชฝ ํ…Œ์ด๋ธ” ๊ธฐ์ค€, ์˜ค๋ฅธ์ชฝ ์—†๋Š” ๊ฐ’์€ NULLLEFT JOIN
RIGHT JOIN์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ” ๋ชจ๋“  ๋ฐ์ดํ„ฐ + ์™ผ์ชฝ ๋งค์นญ ๋ฐ์ดํ„ฐ์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ” ๊ธฐ์ค€, ์™ผ์ชฝ ์—†๋Š” ๊ฐ’์€ NULLRIGHT JOIN
FULL OUTER JOIN๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จNULL๋„ ํฌํ•จํ•˜์—ฌ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐFULL OUTER JOIN
UNION์ค‘๋ณต ์ œ๊ฑฐ ํ›„ ํ•ฉ์ง‘ํ•ฉA์™€ B์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ค‘๋ณต ์—†์ด ๊ฒฐํ•ฉUNION
INTERSECT๊ณตํ†ต๋œ ๊ฐ’๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ๋‘ ํ…Œ์ด๋ธ”์— ๊ณตํ†ต์œผ๋กœ ์กด์žฌํ•˜๋Š” ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜INTERSECT

๐Ÿ”น SQL ์กฐ์ธ ๊ฐœ๋… ๋ฐ ํ™œ์šฉ ์˜ˆ์ œ

1๏ธโƒฃ INNER JOIN โ€“ ๊ณตํ†ต๋œ ๋ฐ์ดํ„ฐ๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ

์˜ˆ์ œ: ๊ณ ๊ฐ๊ณผ ์ฃผ๋ฌธ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ ๊ณตํ†ต๋œ ๊ณ ๊ฐ๋งŒ ์กฐํšŒ

SELECT customers.name, orders.order_id
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;

๊ฒฐ๊ณผ:
โœ… ์ฃผ๋ฌธ์„ ํ•œ ๊ณ ๊ฐ๋งŒ ์กฐํšŒ (์ฃผ๋ฌธ์ด ์—†๋Š” ๊ณ ๊ฐ์€ ์ œ์™ธ๋จ)


2๏ธโƒฃ LEFT JOIN โ€“ ์™ผ์ชฝ ํ…Œ์ด๋ธ” ๊ธฐ์ค€, ์˜ค๋ฅธ์ชฝ์€ NULL ํฌํ•จ

์˜ˆ์ œ: ๋ชจ๋“  ๊ณ ๊ฐ์„ ๊ฐ€์ ธ์˜ค๋˜, ์ฃผ๋ฌธ์ด ์—†๋Š” ๊ณ ๊ฐ๋„ ํฌํ•จ

SELECT customers.name, orders.order_id
FROM customers
LEFT JOIN orders
ON customers.customer_id = orders.customer_id;

๊ฒฐ๊ณผ:
โœ… ์ฃผ๋ฌธ์ด ์—†๋Š” ๊ณ ๊ฐ๋„ ์กฐํšŒ๋˜๋ฉฐ, ์ฃผ๋ฌธ์ด ์—†๋Š” ๊ฒฝ์šฐ NULL ๊ฐ’ ํฌํ•จ


3๏ธโƒฃ RIGHT JOIN โ€“ ์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ” ๊ธฐ์ค€, ์™ผ์ชฝ์€ NULL ํฌํ•จ

์˜ˆ์ œ: ๋ชจ๋“  ์ฃผ๋ฌธ์„ ๊ฐ€์ ธ์˜ค๋˜, ๊ณ ๊ฐ ์ •๋ณด๊ฐ€ ์—†๋Š” ์ฃผ๋ฌธ๋„ ํฌํ•จ

SELECT customers.name, orders.order_id
FROM customers
RIGHT JOIN orders
ON customers.customer_id = orders.customer_id;

๊ฒฐ๊ณผ:
โœ… ์ฃผ๋ฌธ์ด ์žˆ์ง€๋งŒ ๊ณ ๊ฐ ์ •๋ณด๊ฐ€ ์—†๋Š” ๋ฐ์ดํ„ฐ๋„ ํฌํ•จ (์˜ˆ: ํƒˆํ‡ดํ•œ ๊ณ ๊ฐ)


4๏ธโƒฃ FULL OUTER JOIN โ€“ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ํฌํ•จ

์˜ˆ์ œ: ๋ชจ๋“  ๊ณ ๊ฐ๊ณผ ๋ชจ๋“  ์ฃผ๋ฌธ์„ ๊ฐ€์ ธ์˜ค๋˜, ๋งค์นญ๋˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๋Š” NULL ์ฒ˜๋ฆฌ

SELECT customers.name, orders.order_id
FROM customers
FULL OUTER JOIN orders
ON customers.customer_id = orders.customer_id;

๊ฒฐ๊ณผ:
โœ… ๋ชจ๋“  ๊ณ ๊ฐ๊ณผ ๋ชจ๋“  ์ฃผ๋ฌธ์ด ํฌํ•จ๋˜๋ฉฐ, ๋งค์นญ๋˜์ง€ ์•Š๋Š” ๊ฐ’์€ NULL ์ฒ˜๋ฆฌ


5๏ธโƒฃ UNION โ€“ ์ค‘๋ณต ์ œ๊ฑฐ ํ›„ ํ•ฉ์ง‘ํ•ฉ

์˜ˆ์ œ: ๋‘ ๊ฐœ์˜ ์ง€์ ์—์„œ ํŒ๋งค๋œ ์ƒํ’ˆ ๋ชฉ๋ก์„ ํ†ตํ•ฉ

SELECT product_name FROM store1
UNION
SELECT product_name FROM store2;

๊ฒฐ๊ณผ:
โœ… ์ค‘๋ณต๋œ ์ƒํ’ˆ์€ ํ•˜๋‚˜๋งŒ ํฌํ•จ๋จ


6๏ธโƒฃ INTERSECT โ€“ ๊ณตํ†ต๋œ ๊ฐ’๋งŒ ํฌํ•จ

์˜ˆ์ œ: ๋‘ ๊ฐœ์˜ ์ง€์ ์—์„œ ๊ณตํ†ต์ ์œผ๋กœ ํŒ๋งค๋œ ์ƒํ’ˆ ์กฐํšŒ

SELECT product_name FROM store1
INTERSECT
SELECT product_name FROM store2;

๊ฒฐ๊ณผ:
โœ… ๋‘ ์ง€์ ์—์„œ ๋ชจ๋‘ ํŒ๋งค๋˜๋Š” ์ƒํ’ˆ๋งŒ ์ถœ๋ ฅ๋จ


๐Ÿ”น SQL ์กฐ์ธ ํผํฌ๋จผ์Šค ์ตœ์ ํ™” ํŒ

SQL ์กฐ์ธ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.
์•„๋ž˜ ์ตœ์ ํ™” ์ „๋žต์„ ์ ์šฉํ•˜๋ฉด ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ธ ์กฐ์ธ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœ… 1๏ธโƒฃ ON ์กฐ๊ฑด ์ตœ์ ํ™”

  • JOIN์„ ์ˆ˜ํ–‰ํ•  ๋•Œ WHERE๊ฐ€ ์•„๋‹ˆ๋ผ ON์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • ON์— ์‚ฌ์šฉํ•˜๋Š” ์ปฌ๋Ÿผ์€ ์ธ๋ฑ์Šค(INDEX) ์„ค์ •์ด ํ•„์ˆ˜.
SELECT * FROM orders o
INNER JOIN customers c
ON o.customer_id = c.customer_id;

โŒ ๋น„ํšจ์œจ์ ์ธ ์˜ˆ์‹œ (WHERE ์‚ฌ์šฉ)

SELECT * FROM orders o, customers c
WHERE o.customer_id = c.customer_id;

โœ… JOIN ON์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋น ๋ฅด๊ณ  ์ตœ์ ํ™”๋จ


โœ… 2๏ธโƒฃ INDEX(์ธ๋ฑ์Šค) ์„ค์ • ํ•„์ˆ˜

์กฐ์ธ์„ ํ•˜๋Š” ์ปฌ๋Ÿผ์€ ์ธ๋ฑ์Šค๊ฐ€ ์—†์œผ๋ฉด ์†๋„๊ฐ€ ๋А๋ ค์ง„๋‹ค
PRIMARY KEY ๋˜๋Š” FOREIGN KEY๋กœ ์„ค์ •ํ•˜๋ฉด ์„ฑ๋Šฅ ํ–ฅ์ƒ ๊ฐ€๋Šฅ.

CREATE INDEX idx_customer_id ON customers(customer_id);
CREATE INDEX idx_order_id ON orders(order_id);

โœ… ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์กฐ์ธ ์†๋„๊ฐ€ ๋Œ€ํญ ํ–ฅ์ƒ๋จ


โœ… 3๏ธโƒฃ ํ•„์š”ํ•œ ์ปฌ๋Ÿผ๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ

  • SELECT * ๋Œ€์‹  ์ •ํ™•ํ•œ ์ปฌ๋Ÿผ์„ ๋ช…์‹œํ•˜๋ฉด ์„ฑ๋Šฅ์ด ์ข‹์•„์ง
  • ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ค„์ด๋ฉด ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Œ
SELECT customers.name, orders.order_id
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;

โœ… ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ์„ ์ค„์ด๊ณ  ์ตœ์ ํ™”๋œ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ ๊ฐ€๋Šฅ


โœ… 4๏ธโƒฃ EXISTS vs JOIN ๋น„๊ต

  • JOIN์€ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํ•ฉํ•˜๋Š” ๋ฐ ์ตœ์ ํ™”
  • EXISTS๋Š” ์กด์žฌ ์—ฌ๋ถ€๋งŒ ์ฒดํฌํ•˜๋ฏ€๋กœ ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ๋” ์œ ๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์Œ
SELECT * FROM customers c
WHERE EXISTS (
    SELECT 1 FROM orders o WHERE c.customer_id = o.customer_id
);

โœ… ์ฃผ๋ฌธ์ด ์žˆ๋Š” ๊ณ ๊ฐ๋งŒ ์ฐพ์„ ๋•Œ๋Š” EXISTS๊ฐ€ ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Œ


โœ… 5๏ธโƒฃ WITH๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ์ตœ์ ํ™”

  • ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์ตœ์ ํ™”ํ•˜๊ณ  ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Œ
  • ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋ฒˆ ์ค‘๋ณต๋˜๋Š” ์—ฐ์‚ฐ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Œ
WITH FilteredOrders AS (
    SELECT * FROM orders WHERE order_date >= '2024-01-01'
)
SELECT * FROM FilteredOrders o
INNER JOIN customers c
ON o.customer_id = c.customer_id;

โœ… WITH๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐ ๊ฐ€๋…์„ฑ์ด ํ–ฅ์ƒ๋จ


๐Ÿ”น ๊ฒฐ๋ก : SQL ์กฐ์ธ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ™œ์šฉํ•˜์ž

SQL ์กฐ์ธ์€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.
์กฐ์ธ์˜ ๊ฐœ๋…์„ ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๊ณ , ์ตœ์ ํ™”๋œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ํ•ต์‹ฌ ์š”์•ฝ
โœ” INNER JOIN โ€“ ๊ณตํ†ต๋œ ๋ฐ์ดํ„ฐ๋งŒ
โœ” LEFT JOIN โ€“ ์™ผ์ชฝ ๋ฐ์ดํ„ฐ ์ „๋ถ€ ํฌํ•จ
โœ” RIGHT JOIN โ€“ ์˜ค๋ฅธ์ชฝ ๋ฐ์ดํ„ฐ ์ „๋ถ€ ํฌํ•จ
โœ” FULL OUTER JOIN โ€“ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ํฌํ•จ (NULL ํฌํ•จ)
โœ” UNION โ€“ ์ค‘๋ณต ์ œ๊ฑฐ ํ›„ ํ•ฉ์ง‘ํ•ฉ
โœ” INTERSECT โ€“ ๊ณตํ†ต๋œ ๊ฐ’๋งŒ ์ถ”์ถœ

๐ŸŽฏ ํผํฌ๋จผ์Šค ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด

  • ON ์กฐ๊ฑด์„ ์ตœ์ ํ™”ํ•˜๊ณ  WHERE ๋Œ€์‹  ์‚ฌ์šฉ
  • ์ธ๋ฑ์Šค(INDEX) ์„ค์ • ํ•„์ˆ˜
  • ํ•„์š”ํ•œ ์ปฌ๋Ÿผ๋งŒ ์„ ํƒ (SELECT * ์ง€์–‘)
  • EXISTS์™€ JOIN์„ ์ ์ ˆํžˆ ์„ ํƒ
  • ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋Š” WITH๋กœ ์ตœ์ ํ™”

SQL ์กฐ์ธ์€ ๋‹จ์ˆœํ•œ ๊ฐœ๋…์ด์ง€๋งŒ, ์ ์ ˆํ•˜๊ฒŒ ํ™œ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ ์ตœ์ ํ™”๊นŒ์ง€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ํ™œ์šฉํ•˜๋ฉฐ ์ฒด๊ณ„์ ์œผ๋กœ ์ตํ˜€ ๋‚˜๊ฐ€๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

profile
๐Ÿฑ ๋„์ฟ„์—์„œ ํ™œ๋™ ์ค‘์ธ ์›น ๊ฐœ๋ฐœ์ž ๐Ÿ‡ฏ๐Ÿ‡ต๐Ÿ’ป ๐Ÿง‘โ€๐Ÿ’ป ์ตœ๊ทผ์—๋Š” ์š”์ฆ˜IT์—์„œ ์ž‘๊ฐ€๋กœ๋„ ํ™œ๋™ ์ค‘์ž…๋‹ˆ๋‹ค! ๐Ÿ“ ์š”์ฆ˜IT ๊ธ€ ๋ชจ์Œ: https://yozm.wishket.com/magazine/@donghyuk65/

0๊ฐœ์˜ ๋Œ“๊ธ€