๐Ÿ“Œ Oracle SQL ํ•™์Šต ์ •๋ฆฌ - ํ•จ์ˆ˜, ์„œ๋ธŒ์ฟผ๋ฆฌ, GROUP BY, ์กฐ์ธ๊นŒ์ง€ ์ข…ํ•ฉ ์ •๋ฆฌ

My Pale Blue Dotยท2025๋…„ 3์›” 25์ผ
0

DBMS

๋ชฉ๋ก ๋ณด๊ธฐ
5/10
post-thumbnail

๐Ÿ“… ๋‚ ์งœ

2025-03-25


โœ… 1. SQL ํ•จ์ˆ˜(Function) ๊ฐœ๋…

SQL์—์„œ ํ•จ์ˆ˜(Function)๋Š” ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋ฏธ๋ฆฌ ์ •์˜๋œ ๋ช…๋ น์–ด ์ง‘ํ•ฉ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
์ž…๋ ฅ๊ฐ’์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•œ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๊ฑฐ๋‚˜ ๋ถ„์„ํ•  ๋•Œ ํ•„์ˆ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”น ํ•จ์ˆ˜์˜ ์ฃผ์š” ๋ถ„๋ฅ˜

  • ๋‹จ์ผํ–‰ ํ•จ์ˆ˜(Single-Row Function): ๊ฐ ํ–‰๋งˆ๋‹ค ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    ์˜ˆ: UPPER(), ROUND(), TO_CHAR() ๋“ฑ
  • ๋‹ค์ค‘ํ–‰ ํ•จ์ˆ˜(Multi-Row Function): ์—ฌ๋Ÿฌ ํ–‰์„ ํ•˜๋‚˜์˜ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์–ด ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    ์˜ˆ: SUM(), AVG(), COUNT() ๋“ฑ
  • ๋ถ„์„ ํ•จ์ˆ˜(Window Function): ์ง‘๊ณ„๋œ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ ํ–‰์— ๋‹ค์‹œ ์ ์šฉํ•˜์—ฌ ๋ˆ„์  ํ•ฉ๊ณ„, ์ˆœ์œ„ ๋“ฑ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
    ์˜ˆ: RANK(), LAG(), SUM() OVER() ๋“ฑ

์ข‹์•„! ์•„๋ž˜๋Š” ๋ฒจ๋กœ๊ทธ ์—…๋กœ๋“œ์šฉ ๋งˆํฌ๋‹ค์šด ํ˜•์‹์œผ๋กœ ์ •๋ฆฌํ•œ 2, 3, 4, 5๋ฒˆ ํ•ญ๋ชฉ์ด์•ผ.
๊ฐ ํ•ญ๋ชฉ์€ ํ•จ์ˆ˜ ์„ค๋ช… + ์ฝ”๋“œ ์˜ˆ์ œ๊นŒ์ง€ ํฌํ•จํ–ˆ์–ด. ์ด๋Œ€๋กœ ๋ณต์‚ฌํ•ด์„œ ๋ฒจ๋กœ๊ทธ์— ์˜ฌ๋ฆฌ๋ฉด ์™„๋ฒฝํ•ด โœ…

โธป

โœ… 2. ๋‹จ์ผํ–‰ ํ•จ์ˆ˜ ์ •๋ฆฌ

๐Ÿ”น ๋ฌธ์žํ˜• ํ•จ์ˆ˜ (Character Functions)

SELECT name,
       LOWER(name) AS lower_name,
       UPPER(name) AS upper_name,
       INITCAP(name) AS initcap_name,
       LENGTH(name) AS name_len,
       SUBSTR(name, 1, 2) AS first_two_chars,
       INSTR(name, '๊น€') AS position_kim
FROM userTbl;

๐Ÿ”น ์ˆซ์žํ˜• ํ•จ์ˆ˜ (Number Functions)

SELECT price,
       ROUND(price / 1000, 2) AS rounded,
       TRUNC(price / 1000, 1) AS truncated,
       MOD(price, 100) AS remainder,
       CEIL(price / 100) AS ceiled,
       FLOOR(price / 100) AS floored
FROM buyTbl;

๐Ÿ”น ๋‚ ์งœํ˜• ํ•จ์ˆ˜ (Date Functions)

SELECT name, mDate,
       SYSDATE AS today,
       ADD_MONTHS(mDate, 6) AS six_months_later,
       MONTHS_BETWEEN(SYSDATE, mDate) AS months_diff,
       NEXT_DAY(mDate, '๊ธˆ์š”์ผ') AS next_friday,
       LAST_DAY(mDate) AS last_day_of_month
FROM userTbl;

๐Ÿ”น NULL ๊ด€๋ จ ํ•จ์ˆ˜

SELECT name,
       NVL(mobile1, '์—†์Œ') AS nvl_result,
       NVL2(mobile1, '์—ฐ๋ฝ์ฒ˜ ์žˆ์Œ', '๋ฏธ์ž…๋ ฅ') AS contact_check,
       COALESCE(mobile1, mobile2, '๋ฏธ๊ธฐ์žฌ') AS best_contact,
       NULLIF(price, 30) AS null_if_price
FROM userTbl u
JOIN buyTbl b ON u.userID = b.userID;

๐Ÿ”น ์กฐ๊ฑด๋ถ€ ํ•จ์ˆ˜ (CASE, DECODE)

SELECT name, height,
       CASE
           WHEN height >= 180 THEN 'ํ‚ค ํผ'
           WHEN height >= 170 THEN '๋ณดํ†ต'
           ELSE '์ž‘์Œ'
       END AS height_grade
FROM userTbl;

โธป

โœ… 3. ๋‹ค์ค‘ํ–‰ ํ•จ์ˆ˜ (์ง‘๊ณ„ ํ•จ์ˆ˜)

๐Ÿ”น ์ „์ฒด ํ†ต๊ณ„ ๊ณ„์‚ฐ

SELECT COUNT(*) AS ์ „์ฒด์ธ์›,
       COUNT(mobile1) AS ์—ฐ๋ฝ์ฒ˜์ž…๋ ฅ,
       AVG(height) AS ํ‰๊ท ํ‚ค,
       MAX(height) AS ์ตœ๊ณ ํ‚ค,
       MIN(height) AS ์ตœ์ €ํ‚ค,
       STDDEV(height) AS ํ‚คํ‘œ์ค€ํŽธ์ฐจ,
       VARIANCE(height) AS ํ‚ค๋ถ„์‚ฐ
FROM userTbl;

๐Ÿ”น ์ง€์—ญ๋ณ„ ์‚ฌ์šฉ์ž ํ†ต๊ณ„ (GROUP BY)

SELECT addr,
       COUNT(*) AS ์ธ์›์ˆ˜,
       AVG(height) AS ํ‰๊ท ํ‚ค
FROM userTbl
GROUP BY addr;

๐Ÿ”น HAVING ์ ˆ ์‚ฌ์šฉ ์˜ˆ์ œ

SELECT addr, AVG(height) AS ํ‰๊ท ํ‚ค
FROM userTbl
GROUP BY addr
HAVING AVG(height) >= 170;

โธป

โœ… 4. ์„œ๋ธŒ์ฟผ๋ฆฌ ๋ฐ GROUP BY ๊ณ ๊ธ‰

๐Ÿ”น ์ง€์—ญ ํ‰๊ท ๋ณด๋‹ค ๋งŽ์ด ๊ตฌ๋งคํ•œ ์‚ฌ์šฉ์ž (์„œ๋ธŒ์ฟผ๋ฆฌ)

SELECT u.userID, u.addr, SUM(b.price * b.amount) AS ๊ตฌ๋งค์ด์•ก
FROM userTbl u
JOIN buyTbl b ON u.userID = b.userID
GROUP BY u.userID, u.addr
HAVING SUM(b.price * b.amount) > (
    SELECT AVG(total)
    FROM (
        SELECT u2.addr, SUM(b2.price * b2.amount) AS total
        FROM userTbl u2
        JOIN buyTbl b2 ON u2.userID = b2.userID
        GROUP BY u2.addr
        HAVING u2.addr = u.addr
    )
);

๐Ÿ”น ROLLUP

SELECT groupName, SUM(price * amount) AS ํŒ๋งค๊ธˆ์•ก
FROM buyTbl
WHERE groupName IS NOT NULL
GROUP BY ROLLUP(groupName);

๐Ÿ”น CUBE

SELECT groupName, prodName, SUM(price * amount) AS ํŒ๋งค๊ธˆ์•ก
FROM buyTbl
WHERE groupName IS NOT NULL
GROUP BY CUBE(groupName, prodName);

๐Ÿ”น GROUPING SETS

SELECT groupName, prodName, SUM(price * amount) AS ํŒ๋งค๊ธˆ์•ก
FROM buyTbl
WHERE groupName IS NOT NULL
GROUP BY GROUPING SETS((groupName), (prodName), ());

โธป

โœ… 5. ๋ถ„์„ ํ•จ์ˆ˜ (Window Function)

๐Ÿ”น ์ˆœ์œ„ ํ•จ์ˆ˜

SELECT name, height,
       RANK() OVER (ORDER BY height DESC) AS rank_result,
       DENSE_RANK() OVER (ORDER BY height DESC) AS dense_rank_result,
       ROW_NUMBER() OVER (ORDER BY height DESC) AS row_num
FROM userTbl;

๐Ÿ”น ํŒŒํ‹ฐ์…˜๋ณ„ ์ˆœ์œ„

SELECT name, addr, height,
       RANK() OVER (PARTITION BY addr ORDER BY height DESC) AS local_rank
FROM userTbl;

๐Ÿ”น ์ด์ „/๋‹ค์Œ ํ–‰ ์ฐธ์กฐ (LAG, LEAD)

SELECT name, birthYear, height,
       LAG(name, 1, '์—†์Œ') OVER (ORDER BY birthYear) AS ์ด์ „์‚ฌ๋žŒ,
       LEAD(name, 1, '์—†์Œ') OVER (ORDER BY birthYear) AS ๋‹ค์Œ์‚ฌ๋žŒ
FROM userTbl;

๐Ÿ”น ๋ˆ„์  ํ•ฉ๊ณ„

SELECT userID, prodName, price * amount AS ๊ตฌ๋งค๊ธˆ์•ก,
       SUM(price * amount) OVER (PARTITION BY userID ORDER BY num) AS ๋ˆ„์ ๊ตฌ๋งค๊ธˆ์•ก
FROM buyTbl
ORDER BY userID, num;

โธป

โœ… 6. ์กฐ์ธ(Join) ์ •๋ฆฌ

๐Ÿ”น ์กฐ์ธ์ด๋ž€?

์กฐ์ธ(Join)์€ ๋‘ ๊ฐœ ์ด์ƒ์˜ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•˜์—ฌ ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋กœ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” SQL ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ํ…Œ์ด๋ธ” ๊ฐ„ ๊ด€๊ณ„๋ฅผ ์„ค์ •ํ•ด ๋ณตํ•ฉ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ”น INNER JOIN (๋‚ด๋ถ€ ์กฐ์ธ)

์–‘์ชฝ ํ…Œ์ด๋ธ”์—์„œ ์กฐ๊ฑด์ด ์ผ์น˜ํ•˜๋Š” ํ–‰๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

โœ… ํšŒ์›๋ณ„ ์ด ๊ตฌ๋งค ๊ธˆ์•ก

SELECT u.userID, u.name, SUM(b.price * b.amount) AS ์ด๊ตฌ๋งค๊ธˆ์•ก
FROM userTbl u
JOIN buyTbl b ON u.userID = b.userID
GROUP BY u.userID, u.name;

โœ… ํŠน์ • ์ƒํ’ˆ(์˜ˆ: '์ฑ…') ๊ตฌ๋งค ํšŒ์›

SELECT DISTINCT u.name
FROM userTbl u
JOIN buyTbl b ON u.userID = b.userID
WHERE b.prodName = '์ฑ…';

โœ… ๊ฐ€์žฅ ๋งŽ์ด ๊ตฌ๋งคํ•œ ํšŒ์› (์ˆ˜๋Ÿ‰ ๊ธฐ์ค€)

SELECT rownum AS RN, name, ์ด์ˆ˜๋Ÿ‰
FROM (
  SELECT u.name, SUM(b.amount) AS ์ด์ˆ˜๋Ÿ‰
  FROM userTbl u
  JOIN buyTbl b ON u.userID = b.userID
  GROUP BY u.name
  ORDER BY ์ด์ˆ˜๋Ÿ‰ DESC
)
WHERE rownum = 1;

๐Ÿ”น OUTER JOIN (์™ธ๋ถ€ ์กฐ์ธ)

ํ•œ์ชฝ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๊ณ , ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ ์ชฝ์€ NULL๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

โœ… LEFT OUTER JOIN (์™ผ์ชฝ ํ…Œ์ด๋ธ” ๊ธฐ์ค€)

SELECT *
FROM userTbl u
LEFT JOIN buyTbl b ON u.userID = b.userID;

โœ… ๊ตฌ๋งคํ•˜์ง€ ์•Š์€ ํšŒ์› ์ฐพ๊ธฐ (LEFT JOIN + NULL ํ•„ํ„ฐ)

SELECT u.userID, u.name
FROM userTbl u
LEFT JOIN buyTbl b ON u.userID = b.userID
WHERE b.userID IS NULL;

โœ… RIGHT OUTER JOIN (์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ” ๊ธฐ์ค€)

SELECT u.name, b.prodName, b.price
FROM userTbl u
RIGHT JOIN buyTbl b ON u.userID = b.userID;

๐Ÿ”น FULL OUTER JOIN

์–‘์ชฝ ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ํ–‰์„ ์กฐํšŒํ•˜๋ฉฐ, ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๋Š” NULL๋กœ ์ฑ„์›๋‹ˆ๋‹ค.

โœ… ์‹ค์Šต ํ…Œ์ด๋ธ” ์˜ˆ์ œ (studentTbl, examTbl)

-- ํ•™์ƒ ํ…Œ์ด๋ธ”
CREATE TABLE studentTbl (
  studentID CHAR(5) PRIMARY KEY,
  name VARCHAR2(20)
);

-- ์‹œํ—˜ ์‘์‹œ ํ…Œ์ด๋ธ”
CREATE TABLE examTbl (
  examID CHAR(5) PRIMARY KEY,
  studentID CHAR(5),
  subject VARCHAR2(20),
  score NUMBER
);

-- ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
INSERT INTO studentTbl VALUES ('S001', 'ํ™๊ธธ๋™');
INSERT INTO studentTbl VALUES ('S002', '๊น€์ฒ ์ˆ˜');
INSERT INTO studentTbl VALUES ('S003', '์ด์˜ํฌ');
INSERT INTO studentTbl VALUES ('S004', '๋ฐ•์ง€๋ฏผ');

INSERT INTO examTbl VALUES ('E101', 'S001', '์ˆ˜ํ•™', 85);
INSERT INTO examTbl VALUES ('E102', 'S002', '์˜์–ด', 90);
INSERT INTO examTbl VALUES ('E103', 'S005', '๊ตญ์–ด', 88);

โœ… FULL OUTER JOIN ์‹คํ–‰

SELECT s.name AS ํ•™์ƒ์ด๋ฆ„, e.subject AS ๊ณผ๋ชฉ, e.score
FROM studentTbl s
FULL OUTER JOIN examTbl e ON s.studentID = e.studentID;

๐Ÿ”น ์กฐ์ธ ์ •๋ฆฌ ์š”์•ฝํ‘œ

์กฐ์ธ ์œ ํ˜•์„ค๋ช…
INNER JOIN์–‘์ชฝ ํ…Œ์ด๋ธ”์—์„œ ์กฐ๊ฑด์— ๋งž๋Š” ๋ฐ์ดํ„ฐ๋งŒ ๋ฐ˜ํ™˜
LEFT OUTER JOIN์™ผ์ชฝ ํ…Œ์ด๋ธ” ์ „์ฒด + ์˜ค๋ฅธ์ชฝ ์ผ์น˜ํ•˜๋Š” ํ–‰๋งŒ
RIGHT OUTER JOIN์˜ค๋ฅธ์ชฝ ํ…Œ์ด๋ธ” ์ „์ฒด + ์™ผ์ชฝ ์ผ์น˜ํ•˜๋Š” ํ–‰๋งŒ
FULL OUTER JOIN์–‘์ชฝ ํ…Œ์ด๋ธ” ์ „์ฒด + ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด NULL ๋ฐ˜ํ™˜

profile
Here, My Pale Blue.๐ŸŒ

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