๐Ÿ“Œ SQL ์„œ๋ธŒ์ฟผ๋ฆฌ(Subquery) โ€” ์ฟผ๋ฆฌ ์•ˆ์— ์ฟผ๋ฆฌ ๋„ฃ๊ธฐ

scminy0527ยท2026๋…„ 3์›” 13์ผ
post-thumbnail

์„œ๋ธŒ์ฟผ๋ฆฌ๋ž€?

SQL์„ ์ž‘์„ฑํ•˜๋‹ค ๋ณด๋ฉด WHERE ์ ˆ์— ์กฐ๊ฑด์„ ์—ฐ๋‹ฌ์•„ ์“ฐ๊ธฐ ์• ๋งคํ•˜๊ฑฐ๋‚˜,
FROM ์ ˆ์— ๋“ค์–ด๊ฐˆ ํ…Œ์ด๋ธ”์ด ๋จผ์ € ์–ด๋А ์ •๋„ ์ •์ œ๋œ ์ƒํƒœ์—ฌ์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธด๋‹ค.

์ด๋Ÿด ๋•Œ ์„œ๋ธŒ์ฟผ๋ฆฌ(Subquery) ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์„œ๋ธŒ์ฟผ๋ฆฌ๋Š” ์ฟผ๋ฆฌ๋ฌธ ์•ˆ์— ๋˜ ๋‹ค๋ฅธ ์ฟผ๋ฆฌ๋ฌธ์„ ์ค‘์ฒฉํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ,
ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€ ์šฉ๋„๋กœ ํ™œ์šฉ๋œ๋‹ค.

  • ๊ฐ’์œผ๋กœ ํ™œ์šฉ: WHERE ์ ˆ์—์„œ ํŠน์ • ์กฐ๊ฑด ๊ฐ’์„ ๋™์ ์œผ๋กœ ๊ตฌํ•  ๋•Œ
  • ํ…Œ์ด๋ธ”๋กœ ํ™œ์šฉ: FROM ์ ˆ์—์„œ 1์ฐจ ์ •์ œ๋œ ๊ฐ€์ƒ์˜ ํ…Œ์ด๋ธ”๋กœ ์‚ฌ์šฉํ•  ๋•Œ

์‹ค์Šต ํ…Œ์ด๋ธ” ๊ตฌ์„ฑ

์ด๋ฒˆ ์‹ค์Šต์—์„œ๋Š” ์œ ์ €, ๊ฒŒ์‹œ๊ธ€, ๋Œ“๊ธ€ ์„ธ ๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•œ๋‹ค.

-- ์œ ์ € ํ…Œ์ด๋ธ”
CREATE SEQUENCE SEQ_USER;
CREATE TABLE TBL_USER (
    ID            NUMBER CONSTRAINT PK_USER PRIMARY KEY,
    USER_EMAIL    VARCHAR2(255) NOT NULL UNIQUE,
    USER_PASSWORD VARCHAR2(255),
    USER_ADDRESS  VARCHAR2(255),
    USER_BIRTH    DATE
);

-- ๊ฒŒ์‹œ๊ธ€ ํ…Œ์ด๋ธ”
CREATE SEQUENCE SEQ_POST;
CREATE TABLE TBL_POST (
    ID              NUMBER CONSTRAINT PK_POST PRIMARY KEY,
    POST_TITLE      VARCHAR2(255) NOT NULL,
    POST_CONTENT    VARCHAR2(255) NOT NULL,
    POST_CREATE_AT  TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    USER_ID         NUMBER,
    CONSTRAINT FK_POST_USER FOREIGN KEY (USER_ID) REFERENCES TBL_USER(ID)
);

-- ๋Œ“๊ธ€ ํ…Œ์ด๋ธ”
CREATE SEQUENCE SEQ_REPLY;
CREATE TABLE TBL_REPLY (
    ID             NUMBER CONSTRAINT PK_REPLY PRIMARY KEY,
    REPLY_CONTENT  VARCHAR2(255) NOT NULL,
    USER_ID        NUMBER,
    POST_ID        NUMBER,
    CONSTRAINT FK_REPLY_USER FOREIGN KEY (USER_ID) REFERENCES TBL_USER(ID),
    CONSTRAINT FK_REPLY_POST FOREIGN KEY (POST_ID) REFERENCES TBL_POST(ID)
);

ํ…Œ์ด๋ธ”์€ ์™ธ๋ž˜ํ‚ค(FK)๋กœ ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค.
์ด ๊ด€๊ณ„๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ํ™œ์šฉํ•œ ๋‹ค์–‘ํ•œ ์กฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.


๊ธฐ๋ณธ ์„œ๋ธŒ์ฟผ๋ฆฌ ์˜ˆ์‹œ

์•„๋ž˜ ์˜ˆ์‹œ๋Š” TBL_USER์—์„œ ์ฃผ์†Œ๊ฐ€ '๋–ก์žŽ'์„ ํฌํ•จํ•˜๋Š” ์œ ์ €๊ฐ€ ์ž‘์„ฑํ•œ ๊ฒŒ์‹œ๊ธ€์„ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๋‹ค.

SELECT *
FROM TBL_POST
WHERE USER_ID IN (
    SELECT ID
    FROM TBL_USER
    WHERE USER_ADDRESS LIKE '%๋–ก์žŽ%'
);
  • ๋‚ด๋ถ€์˜ ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜์–ด ์กฐ๊ฑด์— ๋งž๋Š” USER_ID ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์™ธ๋ถ€ ์ฟผ๋ฆฌ๋Š” ๊ทธ ๋ชฉ๋ก์„ IN ์กฐ๊ฑด์œผ๋กœ ํ™œ์šฉํ•ด ๊ฒŒ์‹œ๊ธ€์„ ํ•„ํ„ฐ๋งํ•œ๋‹ค.

๋‹จ๊ณ„๋ณ„๋กœ ์„œ๋ธŒ์ฟผ๋ฆฌ ๋งŒ๋“ค๊ธฐ โ€” ๋Œ“๊ธ€์ด ๊ฐ€์žฅ ๋งŽ์€ ๊ฒŒ์‹œ๊ธ€์˜ ์ž‘์„ฑ์ž ์ฐพ๊ธฐ

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


Step 1. ๋Œ“๊ธ€ ์ „์ฒด ํ™•์ธ

SELECT * FROM TBL_REPLY;

Step 2. ๊ฒŒ์‹œ๊ธ€๋ณ„๋กœ ๋Œ“๊ธ€ ์ˆ˜ ์ง‘๊ณ„

SELECT POST_ID, COUNT(POST_ID) AS "REPLY_COUNT"
FROM TBL_REPLY
GROUP BY POST_ID;

Step 3. ๋Œ“๊ธ€ ์ˆ˜ ์ค‘ ์ตœ๋Œ“๊ฐ’ ๊ตฌํ•˜๊ธฐ

SELECT MAX(COUNT(POST_ID))
FROM TBL_REPLY
GROUP BY POST_ID;

Step 4. ๋Œ“๊ธ€ ์ˆ˜๊ฐ€ ์ตœ๋Œ€์ธ ๊ฒŒ์‹œ๊ธ€ ID ์ถ”์ถœ

SELECT POST_ID
FROM TBL_REPLY
GROUP BY POST_ID
HAVING COUNT(POST_ID) = (
    SELECT MAX(COUNT(POST_ID))
    FROM TBL_REPLY
    GROUP BY POST_ID
);

Step 5. ํ•ด๋‹น ๊ฒŒ์‹œ๊ธ€ ์ „์ฒด ์ •๋ณด ์กฐํšŒ

SELECT *
FROM TBL_POST
WHERE ID IN (
    SELECT POST_ID FROM TBL_REPLY
    GROUP BY POST_ID
    HAVING COUNT(POST_ID) = (
        SELECT MAX(COUNT(POST_ID))
        FROM TBL_REPLY
        GROUP BY POST_ID
    )
);

Step 6. ํ•ด๋‹น ๊ฒŒ์‹œ๊ธ€์˜ ์ž‘์„ฑ์ž ID ์ถ”์ถœ

SELECT USER_ID
FROM TBL_POST
WHERE ID IN (
    SELECT POST_ID FROM TBL_REPLY
    GROUP BY POST_ID
    HAVING COUNT(POST_ID) = (
        SELECT MAX(COUNT(POST_ID))
        FROM TBL_REPLY
        GROUP BY POST_ID
    )
);

Step 7. ์ž‘์„ฑ์ž์˜ ์œ ์ € ์ •๋ณด ์ตœ์ข… ์กฐํšŒ

SELECT *
FROM TBL_USER
WHERE ID IN (
    SELECT USER_ID FROM TBL_POST
    WHERE ID IN (
        SELECT POST_ID FROM TBL_REPLY
        GROUP BY POST_ID
        HAVING COUNT(POST_ID) = (
            SELECT MAX(COUNT(POST_ID))
            FROM TBL_REPLY
            GROUP BY POST_ID
        )
    )
);

โš ๏ธ ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ 3๋‹จ๊ณ„๋กœ ์ค‘์ฒฉ๋˜๋ฉด์„œ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.
์ด ๋ฌธ์ œ๋Š” ์ถ”ํ›„ JOIN์„ ํ•™์Šตํ•˜๋ฉด ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ ์„œ๋ธŒ์ฟผ๋ฆฌ๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํžˆ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ํ•ต์‹ฌ์ด๋‹ค.


CASE WHEN โ€” ์กฐ๊ฑด์— ๋”ฐ๋ผ ๊ฐ’ ๋ณ€ํ™˜ํ•˜๊ธฐ

์„œ๋ธŒ์ฟผ๋ฆฌ ์™ธ์—๋„ CASE WHEN ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด
ํŠน์ • ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ถœ๋ ฅ ๊ฐ’์„ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ๋Œ€์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

SELECT
    USER_EMAIL,
    CASE
        WHEN USER_BIRTH >= TO_DATE('2000', 'YYYY') THEN '2000๋…„๋Œ€ ์ƒ'
        WHEN USER_BIRTH <  TO_DATE('2000', 'YYYY') THEN '1990๋…„๋Œ€ ์ƒ'
    END AS "ํƒœ์–ด๋‚œ ๋…„๋„"
FROM TBL_USER;
  • CASE WHEN ... THEN ... END ๊ตฌ์กฐ๋กœ ์กฐ๊ฑด๋ณ„ ๋ถ„๊ธฐ ์ถœ๋ ฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋ณ„์นญ(AS)์„ ๋ถ™์—ฌ ์ปฌ๋Ÿผ ์ด๋ฆ„์„ ๋ณด๊ธฐ ์ข‹๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ •๋ฆฌ

๊ฐœ๋…์„ค๋ช…
์„œ๋ธŒ์ฟผ๋ฆฌ์ฟผ๋ฆฌ ์•ˆ์— ๋˜ ๋‹ค๋ฅธ ์ฟผ๋ฆฌ๋ฅผ ์ค‘์ฒฉํ•˜๋Š” ๋ฐฉ์‹
WHERE IN (์„œ๋ธŒ์ฟผ๋ฆฌ)์„œ๋ธŒ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์กฐ๊ฑด ๊ฐ’์œผ๋กœ ํ™œ์šฉ
HAVING + ์„œ๋ธŒ์ฟผ๋ฆฌ์ง‘๊ณ„ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•„ํ„ฐ๋ง
CASE WHEN์กฐ๊ฑด์— ๋”ฐ๋ผ ์ถœ๋ ฅ ๊ฐ’์„ ๋ณ€ํ™˜
๋‹จ๊ณ„๋ณ„ ์ ‘๊ทผ์„œ๋ธŒ์ฟผ๋ฆฌ๋Š” ํ•œ ๋ฒˆ์— ์™„์„ฑํ•˜๋ ค ํ•˜์ง€ ๋ง๊ณ  ๋‹จ๊ณ„์ ์œผ๋กœ ์ž‘์„ฑ

์„œ๋ธŒ์ฟผ๋ฆฌ์˜ ํ•ต์‹ฌ์€ "๋‹จ๊ณ„๋ณ„๋กœ ์ƒ๊ฐํ•˜๊ธฐ" ๋‹ค.
๋ณต์žกํ•œ ๋ฌธ์ œ์ผ์ˆ˜๋ก ์ž‘์€ ์ฟผ๋ฆฌ๋ถ€ํ„ฐ ๊ฒ€์ฆํ•˜๊ณ  ์Œ“์•„ ์˜ฌ๋ ค์•ผ ํ•œ๋‹ค.
JOIN์„ ๋ฐฐ์šฐ๋ฉด ๋” ๊น”๋”ํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ,
์„œ๋ธŒ์ฟผ๋ฆฌ๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํžˆ ๊ฐ•๋ ฅํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๐Ÿ’ช

profile
๋น„์ „๊ณต์ž์—์„œ ์‹œ์ž‘ํ•ด Flutter๋กœ ์‹ค์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค์—ˆ๊ณ , ๋” ๊นŠ์€ ๊ฐœ๋ฐœ์„ ํ–ฅํ•ด ๊ณ„์† ์„ฑ์žฅ ์ค‘์ธ ๊ฐœ๋ฐœ์ž

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