[DATABASE] DQL SECTION2

์„ฑ์žฅ์ผ๊ธฐยท2024๋…„ 7์›” 2์ผ

[SWCAMP] DB

๋ชฉ๋ก ๋ณด๊ธฐ
4/14

JOIN

๐Ÿ’ก JOIN์€ ๋‘ ๊ฐœ ์ด์ƒ์˜ ํ…Œ์ด๋ธ”์„ ๊ด€๋ จ์žˆ๋Š” ์ปฌ๋Ÿผ์„ ํ†ตํ•ด ๊ฒฐํ•ฉํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

๋‘ ๊ฐœ ์ด์ƒ์˜ ํ…Œ์ด๋ธ”์€ ๋ฐ˜๋“œ์‹œ ์—ฐ๊ด€์žˆ๋Š” ์ปฌ๋Ÿผ์ด ์กด์žฌํ•ด์•ผ ํ•˜๋ฉฐ ์ด๋ฅผ ํ†ตํ•ด JOIN๋œ ํ…Œ์ด๋ธ”๋“ค์˜ ์ปฌ๋Ÿผ์„ ๋ชจ๋‘ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ALIAS

  • SQL๋ฌธ์˜ ์ปฌ๋Ÿผ ๋˜๋Š” ํ…Œ์ด๋ธ”์— ๋ณ„์นญ์„ ๋‹ฌ์•„์ค„ ์ˆ˜ ์žˆ๋‹ค.

  • ์ปฌ๋Ÿผ ๋ณ„์นญ

    • resultSet์˜ ์ปฌ๋Ÿผ๋ช…์ด ๋ณ„์นญ์œผ๋กœ ๋ฐ”๋€œ
    • ๋ณ„์นญ์— ๋„์–ด์“ฐ๊ธฐ๋‚˜ ํŠน์ˆ˜๊ธฐํ˜ธ๊ฐ€ ์—†๋‹ค๋ฉด ํ™‘๋”ฐ์˜ดํ‘œ(')์™€ AS๋Š” ์ƒ๋žต ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ํ…Œ์ด๋ธ” ๋ณ„์นญ

    • ํ…Œ์ด๋ธ”์— ๋ณ„์นญ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์–ด๋–ค ํ…Œ์ด๋ธ” ์†Œ์†์ธ์ง€๋ฅผ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

    • ํ…Œ์ด๋ธ” ๋ณ„์นญ์€ AS๋ฅผ ์จ๋„ ๋˜๊ณ  ์ƒ๋žต๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

      SELECT
             a.category_code
           , a.menu_name
      --   FROM tbl_menu AS a
        FROM tbl_menu a
       ORDER BY a.category_code, a.menu_name;

      ์‹คํ–‰๊ฒฐ๊ณผ

JOIN์˜ ์ข…๋ฅ˜

INNER JOIN

  • ๋‘ ํ…Œ์ด๋ธ”์˜ ๊ต์ง‘ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” SQL JOIN ์œ ํ˜•
  • INNER JOIN์—์„œ INNER ํ‚ค์›Œ๋“œ๋Š” ์ƒ๋žต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
    • ON์„ ํ™œ์šฉํ•œ JOIN

      • ์ปฌ๋Ÿผ๋ช…์ด ๊ฐ™๊ฑฐ๋‚˜ ๋‹ค๋ฅผ ๊ฒฝ์šฐ ON์œผ๋กœ ์„œ๋กœ ์—ฐ๊ด€์žˆ๋Š” ์ปฌ๋Ÿผ์— ๋Œ€ํ•œ ์กฐ๊ฑด์„ ์ž‘์„ฑํ•˜์—ฌ JOINํ•˜๋Š” ๊ฒฝ์šฐ
      SELECT
             a.menu_name
           , b.category_name
      
        FROM tbl_menu a
      --  INNER JOIN tbl_category b ON a.category_code = b.category_code;
        JOIN tbl_category b ON a.category_code = b.category_code;

      ์‹คํ–‰๊ฒฐ๊ณผ

    • USING์„ ํ™œ์šฉํ•œ JOIN

      • ์ปฌ๋Ÿผ๋ช…์ด ๊ฐ™์„ ๊ฒฝ์šฐ USING์œผ๋กœ ์„œ๋กœ ์—ฐ๊ด€์žˆ๋Š” ์ปฌ๋Ÿผ์— ๋Œ€ํ•œ ์กฐ๊ฑด์„ ์ž‘์„ฑํ•˜์—ฌ JOINํ•˜๋Š” ๊ฒฝ์šฐ
      SELECT
             a.menu_name
           , b.category_name
        FROM tbl_menu a
      --  INNER JOIN tbl_category b USING (category_code);
        JOIN tbl_category b USING (category_code);

      ์‹คํ–‰๊ฒฐ๊ณผ

LEFT JOIN

  • ์ฒซ ๋ฒˆ์งธ(์™ผ์ชฝ) ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ์™€ ๋‘ ๋ฒˆ์งธ(์˜ค๋ฅธ์ชฝ) ํ…Œ์ด๋ธ”์—์„œ ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” SQL JOIN ์œ ํ˜•
    SELECT
           a.menu_name
         , b.category_name
      FROM tbl_menu a
      LEFT JOIN tbl_category b ON a.category_code = b.category_code;

    ์‹คํ–‰๊ฒฐ๊ณผ

RIGHT JOIN

  • ๋‘ ๋ฒˆ์งธ(์˜ค๋ฅธ์ชฝ) ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ์™€ ์ฒซ ๋ฒˆ์งธ(์™ผ์ชฝ) ํ…Œ์ด๋ธ”์—์„œ ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” SQL JOIN ์œ ํ˜•
    SELECT                                                          
           a.menu_name                                              
         , b.category_name                                          
      FROM tbl_menu a                                               
     RIGHT JOIN tbl_category b ON a.category_code = b.category_code;

    ์‹คํ–‰๊ฒฐ๊ณผ

CROSS JOIN

  • ๋‘ ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ์กฐํ•ฉ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” SQL JOIN ์œ ํ˜•
    SELECT
           a.menu_name
         , b.category_name
      FROM tbl_menu a
     CROSS JOIN tbl_category b;

    ์‹คํ–‰๊ฒฐ๊ณผ

SELF JOIN

  • ๊ฐ™์€ ํ…Œ์ด๋ธ” ๋‚ด์—์„œ ํ–‰๊ณผ ํ–‰ ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” SQL JOIN ์œ ํ˜•
  • ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋Œ€๋ถ„๋ฅ˜ ํ™•์ธ์„ ์œ„ํ•œ SELF JOIN ์กฐํšŒ
    SELECT
           a.category_name
         , b.category_name
      FROM tbl_category a
      JOIN tbl_category b ON a.ref_category_code = b.category_code
     WHERE a.ref_category_code IS NOT NULL;

    ์‹คํ–‰๊ฒฐ๊ณผ

JOIN ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • MariaDB 5.3 ๋ฒ„์ „๊นŒ์ง€๋Š” ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„(Nested Loop) ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ˜•ํƒœ๋ฐ–์— ์—†์—ˆ์ง€๋งŒ ํ˜„์žฌ๋Š” ๋‹ค์–‘ํ•ด ์กŒ๋‹ค.

    • ๋‹จ์ˆœ ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„(Simple Nested Loop)
      • ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์กฐ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ํ•œ ํ…Œ์ด๋ธ”์˜ ๊ฐ ํ–‰์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ํ–‰์„ ์ˆœํšŒํ•˜๋ฉด์„œ ์กฐ์ธ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
      • ๋งค์šฐ ๋‹จ์ˆœํ•˜์ง€๋งŒ ํฐ ๋ฐ์ดํ„ฐ ์„ธํŠธ์—์„œ๋Š” ๋น„ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ๋‹ค.
    • ๋ธ”๋ก ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„(Block Nested Loop)
      • ๋‹จ์ˆœ ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„๋ฅผ ๊ฐœ์„ ํ•œ ๋ฒ„์ „์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ…Œ์ด๋ธ”(๋“œ๋ผ์ด๋น™ ํ…Œ์ด๋ธ”)๋กœ๋ถ€ํ„ฐ ๋ธ”๋ก ๋‹จ์œ„๋กœ ๋ถˆ๋Ÿฌ์™€์„œ ํ•œ ๋ธ”๋ก์˜ ๋ชจ๋“  ํ–‰์„ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”(๋“œ๋ฆฌ๋ธ ํ…Œ์ด๋ธ”)์˜ ๋ธ”๋ก๊ณผ ๋น„๊ตํ•œ๋‹ค.
      • I/O ์ž‘์—…์„ ์ค„์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
    • ๋ธ”๋ก ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„ ํ•ด์‰ฌ(Block Nested Loop Hash)
      • ๋ธ”๋ก ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ ํ•ด์‰ฌ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜์—ฌ ์กฐ์ธ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ํ–‰์„ ๋” ํšจ์œจ์ ์œผ๋กœ ์ฐพ๋Š”๋‹ค.
      • ํ•ด์‰ฌ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์กฐ์ธ ํ‚ค๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งค์นญํ•  ์ˆ˜ ์žˆ์–ด ์„ฑ๋Šฅ์ด ๋”์šฑ ํ–ฅ์ƒ๋œ๋‹ค.
    • ๋ธ”๋ก ์ธ๋ฑ์Šค(Block Index Join, Batched Key Access)
      • ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์กฐ์ธ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
      • ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ํ–‰๋งŒ์„ ํšจ์œจ์ ์œผ๋กœ ์•ก์„ธ์Šคํ•˜๊ณ , ๋ถˆํ•„์š”ํ•œ ํ–‰์˜ ๊ฒ€์ƒ‰์„ ์ตœ์†Œํ™”ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•œ๋‹ค.
    • ๋ธ”๋ก ์ธ๋ฑ์Šค ํ•ด์‰ฌ(Block Index Hash Join, Batched Key Access Hash)
      • ๋ธ”๋ก ์ธ๋ฑ์Šค ์กฐ์ธ์— ํ•ด์‰ฌ ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋œ ๊ฒƒ์ด๋‹ค.
      • ํ•ด์‰ฌ ํ…Œ์ด๋ธ”์„ ํ™œ์šฉํ•˜์—ฌ ์ธ๋ฑ์Šค์˜ ์กฐ์ธ ์„ฑ๋Šฅ์„ ๋”์šฑ ํ–ฅ์ƒ์‹œ์ผœ ๋น ๋ฅธ ๋งค์นญ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์œ ์šฉํ•˜๋‹ค.
  • ์กฐ์ธ ์บ์‹œ ๋ ˆ๋ฒจ(join_cache_level)

    • MariaDB 10.0์—์„œ๋Š” 4๊ฐ€์ง€ ํ˜•ํƒœ์˜ ๋ธ”๋ก ๊ธฐ๋ฐ˜ ์กฐ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์ด๋“ค์€ ๋ชจ๋‘ ์กฐ์ธ ๋ฒ„ํผ์— ์˜ˆ์ „ ๋ฐฉ์‹์œผ๋กœ ๋ ˆ์ฝ”๋“œ ํ•„๋“œ๋ฅผ ๋ณต์‚ฌํ•˜๋Š” ํ”Œ๋žซ(flat)๋ฐฉ์‹๊ณผ ์ค‘๋ณต๊ฐ’ ์—†์ด ํฌ์ธํ„ฐ๋งŒ ์กฐ์ธ ๋ฒ„ํผ์— ์ €์žฅํ•˜๋Š” ์ธํฌ๋ฆฌ๋ฉ˜ํƒˆ(incremental)๋ฐฉ์‹์ด ์žˆ๋‹ค.
    • BNL
      • ๋ธ”๋ก ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„(Block Nested Loop - Flat)
      • ๋ธ”๋ก ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„(Block Nested Loop - Incremental)
    • BNLH
      • ๋ธ”๋ก ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„ ํ•ด์‰ฌ(Block Nested Loop Hash - Flat)
      • ๋ธ”๋ก ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„ ํ•ด์‰ฌ(Block Nested Loop Hash - Incremental)
    • BKA
      • ๋ฐฐ์น˜ ํ‚ค ์•ก์„ธ์Šค(Batched Key Access - Flat)
      • ๋ฐฐ์น˜ ํ‚ค ์•ก์„ธ์Šค(Batched Key Access - Incremental)
    • BKAH
      • ๋ฐฐ์น˜ ํ‚ค ์•ก์„ธ์Šค ํ•ด์‰ฌ(Batched Key Access Hash - Flat)
      • ๋ฐฐ์น˜ ํ‚ค ์•ก์„ธ์Šค ํ•ด์‰ฌ(Batched Key Access Hash - Incremental)
  • join_cache_level์„ ํ†ตํ•ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ณ ๋ฅผ ์ˆ˜ ์žˆ๋‹ค.

    Server System Variables

DROP TABLE t1;
DROP TABLE t2;

CREATE TABLE t1 (
id int(10) NOT NULL AUTO_INCREMENT ,
c1 int(10) NOT NULL DEFAULT '0',
c2 int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (id),
KEY idx_c1 (c1)
) ENGINE=InnoDB;

CREATE TABLE t2 (
id int(10) NOT NULL AUTO_INCREMENT ,
c1 int(10) NOT NULL DEFAULT '0',
c2 int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (id),
KEY idx_c1 (c1)
) ENGINE=InnoDB;

insert into t1 select null,round(rand()*100),round(rand()*1000)
from information_schema.columns a1, information_schema.columns b1  
LIMIT 100;

insert INTO t2 select null,round(rand()*100),round(rand()*1000)
from information_schema.columns a1, information_schema.columns b1  
LIMIT 100;

SELECT * FROM t1;
SELECT * FROM t2;

BLOCK NESTED LOOP(BNL)

  • MariaDB(MySQL)์€ ๊ธฐ๋ณธ์ ์œผ๋กœ BLOCK NESTED LOOP JOIN์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋‘ ๊ฐœ ์ด์ƒ์˜ ํ…Œ์ด๋ธ”์—์„œ ํ•˜๋‚˜์˜ ์ง‘ํ•ฉ์„ ๊ธฐ์ค€์œผ๋กœ ์ˆœ์ฐจ์ ์œผ๋กœ ์ƒ๋Œ€๋ฐฉ Row๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์กฐํ•ฉํ•˜๋Š” ๋ฐฉ์‹
  • ์ค‘์ฒฉ ๋ฐ˜๋ณต๋ฌธ์ฒ˜๋Ÿผ ์ฒซ๋ฒˆ ์งธ ํ…Œ์ด๋ธ”์˜ Row์™€ ๊ด€๋ จ๋œ ๋‘๋ฒˆ์งธ ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ Row๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์ดํ›„ ์ฒซ ๋ฒˆ์งธ ํ…Œ์ด๋ธ”์˜ ๋‹ค์Œ Row์— ๋Œ€ํ•ด ๋‘๋ฒˆ์งธ ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ๊ฒƒ์„ ๊ฒ€์ƒ‰ํ•˜๋ฉฐ ์ดํ›„ ์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
    SET SESSION optimizer_switch='join_cache_incremental=on';
    SET SESSION optimizer_switch='join_cache_hashed=on';
    SET SESSION optimizer_switch='join_cache_bka=on';
    SET SESSION join_cache_level=2;
    
    select count(*) from t1 join t2 on t1.c2 = t2.c2;
    explain select count(*) from t1 join t2 on t1.c2 = t2.c2;

    ์‹คํ–‰๊ฒฐ๊ณผ

Block Nested Loop Hash(BNLH)

  • MySQL8.0.18๋ฒ„์ „ ์ดํ›„ ์ง€์›ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
  • ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์„ธํŠธ์— ๋Œ€ํ•œ ์กฐ์ธ ์—ฐ์‚ฐ์„ ํšจ๊ณผ์ ์œผ๋กœ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋นŒ๋“œ ๋‹จ๊ณ„(Build phase): ํ•ด์‹ฑ ๋‹จ๊ณ„์—์„œ ์กฐ์ธ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋‘ ํ…Œ์ด๋ธ” ์ค‘ ์ž‘์€ ์ชฝ์„ ์„ ํƒํ•˜์—ฌ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์–ด ๋ฉ”๋ชจ๋ฆฌ(PGA ์˜์—ญ)์— ์ €์žฅํ•˜๊ณ  ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ ํ–‰์„ ํŠน์ • "ํ•ด์‹œ ๋ฒ„ํ‚ท"์— ํ• ๋‹นํ•œ๋‹ค.
  • ํ”„๋กœ๋ธŒ ๋‹จ๊ณ„(Probe phase): ์กฐ์ธ ๋‹จ๊ณ„์—์„œ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์„ ์ˆœํšŒํ•˜๋ฉฐ ๊ฐ ํ–‰์— ๋Œ€ํ•ด ๋™์ผํ•œ ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ํ–‰์ด ์–ด๋–ค ๋ฒ„ํ‚ท์— ์†ํ•˜๋Š”์ง€ ๊ฒฐ์ •ํ•˜๊ณ  ์ด ๋ฒ„ํ‚ท์˜ ๋ชจ๋“  ํ–‰๊ณผ ํ•ด๋‹น ํ–‰์„ ๋น„๊ตํ•˜์—ฌ ์กฐ์ธ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•œ๋‹ค.
  • ์ด ๋ฐฉ๋ฒ•์€ ์กฐ์ธํ•  ํ…Œ์ด๋ธ” ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ์ ํ•ฉํ•  ๋งŒํผ ์ถฉ๋ถ„ํžˆ ์ž‘์•„์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ•ด์‹œ ํ…Œ์ด๋ธ”์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋„˜์–ด์„œ ๋””์Šคํฌ๋กœ๊นŒ์ง€ ๋„˜์–ด๊ฐ€๊ณ  ์ด๋Š” ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ดˆ๋ž˜ํ•œ๋‹ค.
  • HASH JOIN์€ ๋“ฑ๊ฐ€ ์กฐ์ธ('=' ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์กฐ์ธ)์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ๋น„๋“ฑ๊ฐ€ ์กฐ์ธ์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
    SET SESSION optimizer_switch='join_cache_incremental=on';
    SET SESSION optimizer_switch='join_cache_hashed=on';
    SET SESSION optimizer_switch='join_cache_bka=on';
    SET SESSION join_cache_level=3;
    
    select count(*) from t1 join t2 on t1.c2 = t2.c2;
    explain select count(*) from t1 join t2 on t1.c2 = t2.c2;
    
    -- join_cache_hashed๋ฅผ off๋กœ ํ•˜๋ฉด BNL ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.
    -- SET SESSION optimizer_switch='join_cache_hashed=on';
    -- explain select count(*) from t1 join t2 on t1.c2 = t2.c2;

    ์‹คํ–‰๊ฒฐ๊ณผ

GROUPING

๐Ÿ’ก GROUP BY์ ˆ์€ ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์„ ํŠน์ • ์—ด์˜ ๊ฐ’์— ๋”ฐ๋ผ ๊ทธ๋ฃนํ™”ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

HAVING์€ GROUP BY ์ ˆ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ ๊ทธ๋ฃน์— ๋Œ€ํ•œ ์กฐ๊ฑด์„ ์ ์šฉํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

GROUP BY

  • GROUP BY๋ฅผ ํ™œ์šฉํ•œ ๋ฉ”๋‰ด๊ฐ€ ์กด์žฌํ•˜๋Š” ์นดํ…Œ๊ณ ๋ฆฌ ๊ทธ๋ฃน ์กฐํšŒ

    SELECT
           category_code
      FROM tbl_menu
     GROUP BY category_code;

    ์‹คํ–‰๊ฒฐ๊ณผ

  • COUNT ํ•จ์ˆ˜ ํ™œ์šฉ

    SELECT
           category_code
         , COUNT(*)
      FROM tbl_menu
     GROUP BY category_code;

    ์‹คํ–‰๊ฒฐ๊ณผ

  • SUM ํ•จ์ˆ˜ ํ™œ์šฉ

    SELECT
           category_code
         , SUM(menu_price)
      FROM tbl_menu
     GROUP BY category_code;

    ์‹คํ–‰๊ฒฐ๊ณผ

  • AVG ํ•จ์ˆ˜ ํ™œ์šฉ

    SELECT
           category_code
         , AVG(menu_price)
      FROM tbl_menu
     GROUP BY category_code;

    ์‹คํ–‰๊ฒฐ๊ณผ

  • 2๊ฐœ ์ด์ƒ์˜ ๊ทธ๋ฃน ์ƒ์„ฑ

    SELECT
           menu_price
         , category_code
      FROM tbl_menu
     GROUP BY menu_price, category_code; 

    ์‹คํ–‰๊ฒฐ๊ณผ

  • join๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉ

    SELECT
           a.category_code
         , b.category_name
         , AVG(menu_price)
      FROM tbl_menu a
      JOIN tbl_category b ON (a.category_code = b.category_code)
     GROUP BY a.category_code, b.category_name;

    ์‹คํ–‰๊ฒฐ๊ณผ

HAVING

  • HAVING์„ ํ™œ์šฉํ•ด 5๋ฒˆ(์ค‘์‹) ์นดํ…Œ๊ณ ๋ฆฌ๋ถ€ํ„ฐ 8๋ฒˆ(์ปคํ”ผ) ์นดํ…Œ๊ณ ๋ฆฌ๊นŒ์ง€์˜ ๋ฉ”๋‰ด ์นดํ…Œ๊ณ ๋ฆฌ ๋ฒˆํ˜ธ ์กฐํšŒ
    SELECT                               
           category_code                 
      FROM tbl_menu                      
     GROUP BY category_code              
    HAVING category_code BETWEEN 5 AND 8;

    ์‹คํ–‰๊ฒฐ๊ณผ

ROLLUP

  • ์ปฌ๋Ÿผ ํ•œ ๊ฐœ๋ฅผ ํ™œ์šฉํ•œ ROLLUP(์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์ดํ•ฉ)

    SELECT
           category_code
         , SUM(menu_price)
      FROM tbl_menu
     GROUP BY category_code
      WITH ROLLUP;

    ์‹คํ–‰๊ฒฐ๊ณผ

  • ์ปฌ๋Ÿผ ๋‘ ๊ฐœ๋ฅผ ํ™œ์šฉํ•œ ROLLUP(๊ฐ™์€ ๋ฉ”๋‰ด ๊ฐ€๊ฒฉ๋ณ„ ์ดํ•ฉ ๋ฐ ํ•ด๋‹น ๋ฉ”๋‰ด ๊ฐ€๊ฒฉ๋ณ„ ๊ฐ™์€ ์นดํ…Œ๊ณ ๋ฆฌ์˜ ์ดํ•ฉ๊ณผ ์ „์ฒด )

    • ROLLUP์„ ํ†ตํ•ด ๋จผ์ € ๋‚˜์˜จ ์ปฌ๋Ÿผ์˜ ์ดํ•ฉ์„ ๊ตฌํ•˜๊ณ  ์ดํ›„ ๋‚˜์˜ค๋Š” ์ปฌ๋Ÿผ๊ณผ์˜ ํ•ฉ๋„ ๊ตฌํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

      SELECT
             menu_price
           , category_code
           , SUM(menu_price)
        FROM tbl_menu
       GROUP BY menu_price, category_code
        WITH ROLLUP;

      ์‹คํ–‰๊ฒฐ๊ณผ

  • ์—ฐ๋„๋ณ„, ์›”๋ณ„, ์ƒํ’ˆ๋ณ„ ํ•ฉ๊ณ„๋ฅผ ๊ตฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

    CREATE TABLE sales (
        code INT AUTO_INCREMENT,
        year VARCHAR(4),
        month VARCHAR(2),
        product VARCHAR(50),
        amount DECIMAL(10,2),
        PRIMARY KEY(code)
    );
    
    INSERT INTO sales (code, year, month, product, amount) VALUES
    (null, '2023', LPAD('1', 2, '0'), 'Product A', 1000.00),
    (null, '2023', LPAD('1', 2, '0'), 'Product B', 1500.00),
    (null, '2023', LPAD('2', 2, '0'), 'Product A', 2000.00),
    (null, '2023', LPAD('2', 2, '0'), 'Product B', 2500.00),
    (null, '2023', LPAD('3', 2, '0'), 'Product A', 1200.00),
    (null, '2024', LPAD('3', 2, '0'), 'Product B', 1700.00);
    
    SELECT
           year
    	   , month
    	   , product
    	   , SUM(amount) AS total_sales
      FROM sales
     GROUP BY year, month, product WITH ROLLUP;

    ์‹คํ–‰๊ฒฐ๊ณผ

SUBQUERIES

๐Ÿ’ก SUBQUERY๋Š” ๋‹ค๋ฅธ ์ฟผ๋ฆฌ ๋‚ด์—์„œ ์‹คํ–‰๋˜๋Š” ์ฟผ๋ฆฌ์ด๋‹ค.

SUBQUERY์˜ ๊ฒฐ๊ณผ๋ฅผ ํ™œ์šฉํ•ด์„œ ๋ณต์žกํ•œ MAINQUERY๋ฅผ ์ž‘์„ฑํ•ด ํ•œ๋ฒˆ์— ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

SUBQUERY ํ™œ์šฉ

  • ์„œ๋ธŒ์ฟผ๋ฆฌ์™€ ๋ฉ”์ธ ์ฟผ๋ฆฌ๋ฅผ ํ™œ์šฉํ•œ ๋‹ค์ค‘์—ด ๊ฒฐ๊ณผ ์กฐํšŒ
    • ์„œ๋ธŒ์ฟผ๋ฆฌ

      SELECT
             category_code
        FROM tbl_menu
       WHERE menu_name = '๋ฏผํŠธ๋ฏธ์—ญ๊ตญ';

      ์‹คํ–‰๊ฒฐ๊ณผ

    • ๋ฉ”์ธ์ฟผ๋ฆฌ

      SELECT
             menu_code
           , menu_name
           , menu_price
           , category_code
           , orderable_status
        FROM tbl_menu;

      ์‹คํ–‰๊ฒฐ๊ณผ

    • ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ํ™œ์šฉํ•œ ๋ฉ”์ธ ์ฟผ๋ฆฌ

      SELECT                                                   
             menu_code                                         
           , menu_name                                         
           , menu_price                                        
           , category_code                                     
           , orderable_status                                  
        FROM tbl_menu                                          
       WHERE category_code = (SELECT category_code             
                                FROM tbl_menu                  
                               WHERE menu_name = '๋ฏผํŠธ๋ฏธ์—ญ๊ตญ');

      ์‹คํ–‰๊ฒฐ๊ณผ

  • SUBQUERY๋ฅผ ํ™œ์šฉํ•ด ๊ฐ€์žฅ ๋งŽ์€ ๋ฉ”๋‰ด๊ฐ€ ํฌํ•จ๋œ ์นดํ…Œ๊ณ ๋ฆฌ ์กฐํšŒ
    • ์„œ๋ธŒ์ฟผ๋ฆฌ

      SELECT
             COUNT(*) AS 'count'
        FROM tbl_menu
       GROUP BY category_code;

      ์‹คํ–‰๊ฒฐ๊ณผ

    • ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ํ™œ์šฉํ•œ ๋ฉ”์ธ ์ฟผ๋ฆฌ
      - FROM ์ ˆ์— ์“ฐ์ธ ์„œ๋ธŒ์ฟผ๋ฆฌ(derived table, ํŒŒ์ƒ ํ…Œ์ด๋ธ”)๋Š” ๋ฐ˜๋“œ์‹œ ์ž์‹ ์˜ ๋ณ„์นญ์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.(feat. ์ด๋Ÿฌํ•œ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ โ€˜์ธ๋ผ์ธ ๋ทฐโ€™๋ผ๊ณ  ํ•œ๋‹ค.)

      SELECT
             MAX(count)
        FROM (SELECT COUNT(*) AS 'count'
                FROM tbl_menu
               GROUP BY category_code) AS countmenu;

      ์‹คํ–‰๊ฒฐ๊ณผ

์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ

  • ๋ฉ”์ธ ์ฟผ๋ฆฌ๊ฐ€ ์„œ๋ธŒ์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ๊ฒฝ์šฐ ์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ผ๊ณ  ํ•œ๋‹ค.
  • SUBQUERY๋ฅผ ํ™œ์šฉํ•ด ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ํ‰๊ท  ๊ฐ€๊ฒฉ๋ณด๋‹ค ๋†’์€ ๊ฐ€๊ฒฉ์˜ ๋ฉ”๋‰ด ์กฐํšŒ
    • ์„œ๋ธŒ์ฟผ๋ฆฌ

      SELECT
             AVG(menu_price)
        FROM tbl_menu
       WHERE category_code = 4;

      ์‹คํ–‰๊ฒฐ๊ณผ

    • ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ํ™œ์šฉํ•œ ๋ฉ”์ธ ์ฟผ๋ฆฌ

      SELECT                                                   
             menu_code                                         
           , menu_name                                         
           , menu_price                                        
           , category_code                                     
           , orderable_status                                  
        FROM tbl_menu a     
                                           
       WHERE menu_price > (SELECT AVG(menu_price)
                             FROM tbl_menu                  
                            WHERE category_code = a.category_code);

      ์‹คํ–‰๊ฒฐ๊ณผ

EXISTS

  • ์กฐํšŒ ๊ฒฐ๊ณผ๊ฐ€ ์žˆ์„ ๋•Œ true ์•„๋‹ˆ๋ฉด false
  • EXISTS์™€ SUBQUERY๋ฅผ ํ™œ์šฉํ•œ ๋ฉ”๋‰ด๊ฐ€ ์žˆ๋Š” ์นดํ…Œ๊ณ ๋ฆฌ ์กฐํšŒ
    SELECT
           category_name
      FROM tbl_category a
     WHERE EXISTS(SELECT 1
                    FROM tbl_menu b
                    WHERE b.category_code = a.category_code)
    	 ORDER BY 1;

์‹คํ–‰๊ฒฐ๊ณผ

  • ํŒŒ์ƒ ํ…Œ์ด๋ธ”๊ณผ ๋น„์Šทํ•œ ๊ฐœ๋…์ด๋ฉฐ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ๊ณผ ์žฌ์‚ฌ์šฉ์„ฑ์„ ์œ„ํ•ด ํŒŒ์ƒ ํ…Œ์ด๋ธ” ๋Œ€์‹  ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.)

CTE(Common Table Expressions)

  • FROM์ ˆ์—์„œ๋งŒ ์‚ฌ์šฉ ๋จ(JOIN์ผ ์‹œ JOIN ๊ตฌ๋ฌธ์—์„œ๋„ ๊ฐ€๋Šฅ)
  • ์ธ๋ผ์ธ ๋ทฐ๋กœ ์“ฐ์ธ ์„œ๋ธŒ์ฟผ๋ฆฌ(FROM ์ ˆ์— ์“ฐ์ธ ์„œ๋ธŒ์ฟผ๋ฆฌ)๋ฅผ ๋ฏธ๋ฆฌ ์ •์˜ํ•˜๊ณ  ๋ฉ”์ธ์ฟผ๋ฆฌ๊ฐ€ ์‹ฌํ”Œํ•ด ์งˆ ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ๋ฒ•
    WITH menucate AS (
        SELECT menu_name
             , category_name
          FROM tbl_menu a
          JOIN tbl_category b ON a.category_code = b.category_code
    )
    SELECT
           *
      FROM menucate
     ORDER BY menu_name;

    ์‹คํ–‰๊ฒฐ๊ณผ

SET OPERATORS

๐Ÿ’ก SET ์—ฐ์‚ฐ์ž๋Š” ๋‘ ๊ฐœ ์ด์ƒ์˜ SELECT๋ฌธ์˜ ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์„ ๊ฒฐํ•ฉํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

SET ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์˜ ์ปฌ๋Ÿผ์ด ๋™์ผํ•ด์•ผ ํ•œ๋‹ค.

UNION

  • ๋‘ ๊ฐœ ์ด์ƒ์˜ SELECT ๋ฌธ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์ค‘๋ณต๋œ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•œ ํ›„ ๋ฐ˜ํ™˜ํ•˜๋Š” SQL ์—ฐ์‚ฐ์ž์ด๋‹ค.
    SELECT
           menu_code
         , menu_name
         , menu_price
         , category_code
         , orderable_status
      FROM tbl_menu
     WHERE category_code = 10
     UNION
    SELECT
           menu_code
         , menu_name
         , menu_price
         , category_code
         , orderable_status
      FROM tbl_menu
     WHERE menu_price < 9000;

์‹คํ–‰๊ฒฐ๊ณผ

UNION ALL

  • ๋‘ ๊ฐœ ์ด์ƒ์˜ SELECT ๋ฌธ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฒฐํ•ฉํ•˜๋ฉฐ ์ค‘๋ณต๋œ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜์ง€ ์•Š๊ณ  ๋ชจ๋‘ ๋ฐ˜ํ™˜ํ•˜๋Š” SQL ์—ฐ์‚ฐ์ž์ด๋‹ค.
    SELECT
           menu_code
         , menu_name
         , menu_price
         , category_code
         , orderable_status
      FROM tbl_menu
     WHERE category_code = 10
     UNION ALL
    SELECT
           menu_code
         , menu_name
         , menu_price
         , category_code
         , orderable_status
      FROM tbl_menu
     WHERE menu_price < 9000;

    ์‹คํ–‰๊ฒฐ๊ณผ

INTERSECT

  • ๋‘ SELECT ๋ฌธ์˜ ๊ฒฐ๊ณผ ์ค‘ ๊ณตํ†ต๋˜๋Š” ๋ ˆ์ฝ”๋“œ๋งŒ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” SQL ์—ฐ์‚ฐ์ž์ด๋‹ค.
  • MySQL์€ ๋ณธ๋ž˜ ๊ธฐ๋ณธ์ ์œผ๋กœ INTERSECT๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค. ํ•˜์ง€๋งŒ INNER JOIN ๋˜๋Š” IN ์—ฐ์‚ฐ์ž ํ™œ์šฉํ•ด์„œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜๋‹ค.
    • INNER JOIN ํ™œ์šฉ

      SELECT
             a.menu_code
           , a.menu_name
           , a.menu_price
           , a.category_code
           , a.orderable_status
        FROM tbl_menu a
       INNER JOIN (SELECT menu_code
                        , menu_name
                        , menu_price
                        , category_code
                        , orderable_status
                     FROM tbl_menu
                    WHERE menu_price < 9000) b ON (a.menu_code = b.menu_code)
       WHERE a.category_code = 10;

      ์‹คํ–‰๊ฒฐ๊ณผ

    • IN ์—ฐ์‚ฐ์ž ํ™œ์šฉ

      SELECT
             a.menu_code
           , a.menu_name
           , a.menu_price
           , a.category_code
           , a.orderable_status
        FROM tbl_menu a
       WHERE category_code = 10 
         AND menu_code IN (SELECT menu_code
                             FROM tbl_menu
                            WHERE menu_price < 9000);

      ์‹คํ–‰๊ฒฐ๊ณผ

MINUS

  • ์ฒซ ๋ฒˆ์งธ SELECT ๋ฌธ์˜ ๊ฒฐ๊ณผ์—์„œ ๋‘ ๋ฒˆ์งธ SELECT ๋ฌธ์˜ ๊ฒฐ๊ณผ๊ฐ€ ํฌํ•จํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์ œ์™ธํ•œ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” SQL ์—ฐ์‚ฐ์ž์ด๋‹ค.
  • MySQL์€ MINUS๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค. ํ•˜์ง€๋งŒ LEFT JOIN์„ ํ™œ์šฉํ•ด์„œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜๋‹ค.
    SELECT
           a.menu_code
         , a.menu_name
         , a.menu_price
         , a.category_code
         , a.orderable_status
      FROM tbl_menu a
      LEFT JOIN (SELECT menu_code
                      , menu_name
                      , menu_price
                      , category_code
                      , orderable_status
                   FROM tbl_menu b
                  WHERE menu_price < 9000) b ON (a.menu_code = b.menu_code)
     WHERE a.category_code = 10
       AND b.menu_code IS NULL;

    ์‹คํ–‰๊ฒฐ๊ณผ

6๊ฐ€์ง€ ์ ˆ์˜ ์ข…๋ฅ˜์™€ ์‹คํ–‰ ์ˆœ์„œ

ex)

select                            -- 5th
from (join)                       -- 1st
where (ํ•œ ํ–‰ ์”ฉ ์กฐ๊ฑด์„ ๋ถ„๋ณ„)        -- 2nd
group by                          -- 3rd
having (๊ทธ๋ฃน๋ณ„๋กœ ์กฐ๊ฑด)              -- 4th
order by (limit)                  -- 6th
  • ํ™œ์šฉ ๋ฐ์ดํ„ฐ์…‹
-- ํ…Œ์ด๋ธ” ์‚ญ์ œ
DROP TABLE IF EXISTS tbl_payment_order CASCADE;
DROP TABLE IF EXISTS tbl_payment CASCADE;
DROP TABLE IF EXISTS tbl_order_menu CASCADE;
DROP TABLE IF EXISTS tbl_order CASCADE;
DROP TABLE IF EXISTS tbl_menu CASCADE;
DROP TABLE IF EXISTS tbl_category CASCADE;

-- ํ…Œ์ด๋ธ” ์ƒ์„ฑ
-- category ํ…Œ์ด๋ธ” ์ƒ์„ฑ
CREATE TABLE IF NOT EXISTS tbl_category
(
    category_code    INT AUTO_INCREMENT COMMENT '์นดํ…Œ๊ณ ๋ฆฌ์ฝ”๋“œ',
    category_name    VARCHAR(30) NOT NULL COMMENT '์นดํ…Œ๊ณ ๋ฆฌ๋ช…',
    ref_category_code    INT COMMENT '์ƒ์œ„์นดํ…Œ๊ณ ๋ฆฌ์ฝ”๋“œ',
    CONSTRAINT pk_category_code PRIMARY KEY (category_code),
    CONSTRAINT fk_ref_category_code FOREIGN KEY (ref_category_code) REFERENCES tbl_category (category_code)
) ENGINE=INNODB COMMENT '์นดํ…Œ๊ณ ๋ฆฌ';

CREATE TABLE IF NOT EXISTS tbl_menu
(
    menu_code    INT AUTO_INCREMENT COMMENT '๋ฉ”๋‰ด์ฝ”๋“œ',
    menu_name    VARCHAR(30) NOT NULL COMMENT '๋ฉ”๋‰ด๋ช…',
    menu_price    INT NOT NULL COMMENT '๋ฉ”๋‰ด๊ฐ€๊ฒฉ',
    category_code    INT NOT NULL COMMENT '์นดํ…Œ๊ณ ๋ฆฌ์ฝ”๋“œ',
    orderable_status    CHAR(1) NOT NULL COMMENT '์ฃผ๋ฌธ๊ฐ€๋Šฅ์ƒํƒœ',
    CONSTRAINT pk_menu_code PRIMARY KEY (menu_code),
    CONSTRAINT fk_category_code FOREIGN KEY (category_code) REFERENCES tbl_category (category_code)
) ENGINE=INNODB COMMENT '๋ฉ”๋‰ด';

CREATE TABLE IF NOT EXISTS tbl_order
(
    order_code    INT AUTO_INCREMENT COMMENT '์ฃผ๋ฌธ์ฝ”๋“œ',
    order_date    VARCHAR(8) NOT NULL COMMENT '์ฃผ๋ฌธ์ผ์ž',
    order_time    VARCHAR(8) NOT NULL COMMENT '์ฃผ๋ฌธ์‹œ๊ฐ„',
    total_order_price    INT NOT NULL COMMENT '์ด์ฃผ๋ฌธ๊ธˆ์•ก',
    CONSTRAINT pk_order_code PRIMARY KEY (order_code)
) ENGINE=INNODB COMMENT '์ฃผ๋ฌธ';

CREATE TABLE IF NOT EXISTS tbl_order_menu
(
    order_code INT NOT NULL COMMENT '์ฃผ๋ฌธ์ฝ”๋“œ',
    menu_code    INT NOT NULL COMMENT '๋ฉ”๋‰ด์ฝ”๋“œ',
    order_amount    INT NOT NULL COMMENT '์ฃผ๋ฌธ์ˆ˜๋Ÿ‰',
    CONSTRAINT pk_comp_order_menu_code PRIMARY KEY (order_code, menu_code),
    CONSTRAINT fk_order_menu_order_code FOREIGN KEY (order_code) REFERENCES tbl_order (order_code),
    CONSTRAINT fk_order_menu_menu_code FOREIGN KEY (menu_code) REFERENCES tbl_menu (menu_code)
) ENGINE=INNODB COMMENT '์ฃผ๋ฌธ๋ณ„๋ฉ”๋‰ด';

CREATE TABLE IF NOT EXISTS tbl_payment
(
    payment_code    INT AUTO_INCREMENT COMMENT '๊ฒฐ์ œ์ฝ”๋“œ',
    payment_date    VARCHAR(8) NOT NULL COMMENT '๊ฒฐ์ œ์ผ',
    payment_time    VARCHAR(8) NOT NULL COMMENT '๊ฒฐ์ œ์‹œ๊ฐ„',
    payment_price    INT NOT NULL COMMENT '๊ฒฐ์ œ๊ธˆ์•ก',
    payment_type    VARCHAR(6) NOT NULL COMMENT '๊ฒฐ์ œ๊ตฌ๋ถ„',
    CONSTRAINT pk_payment_code PRIMARY KEY (payment_code)
) ENGINE=INNODB COMMENT '๊ฒฐ์ œ';

CREATE TABLE IF NOT EXISTS tbl_payment_order
(
    order_code    INT NOT NULL COMMENT '์ฃผ๋ฌธ์ฝ”๋“œ',
    payment_code    INT NOT NULL COMMENT '๊ฒฐ์ œ์ฝ”๋“œ',
    CONSTRAINT pk_comp_payment_order_code PRIMARY KEY (payment_code, order_code),
    CONSTRAINT fk_payment_order_order_code FOREIGN KEY (order_code) REFERENCES tbl_order (order_code),
    CONSTRAINT fk_payment_order_payment_code FOREIGN KEY (order_code) REFERENCES tbl_payment (payment_code)
) ENGINE=INNODB COMMENT '๊ฒฐ์ œ๋ณ„์ฃผ๋ฌธ';

-- ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
INSERT INTO tbl_category VALUES (null, '์‹์‚ฌ', null);
INSERT INTO tbl_category VALUES (null, '์Œ๋ฃŒ', null);
INSERT INTO tbl_category VALUES (null, '๋””์ €ํŠธ', null);
INSERT INTO tbl_category VALUES (null, 'ํ•œ์‹', 1);
INSERT INTO tbl_category VALUES (null, '์ค‘์‹', 1);

INSERT INTO tbl_category VALUES (null, '์ผ์‹', 1);
INSERT INTO tbl_category VALUES (null, 'ํ“จ์ „', 1);
INSERT INTO tbl_category VALUES (null, '์ปคํ”ผ', 2);
INSERT INTO tbl_category VALUES (null, '์ฅฌ์Šค', 2);
INSERT INTO tbl_category VALUES (null, '๊ธฐํƒ€', 2);

INSERT INTO tbl_category VALUES (null, '๋™์–‘', 3);
INSERT INTO tbl_category VALUES (null, '์„œ์–‘', 3);

INSERT INTO tbl_menu VALUES (null, '์—ด๋ฌด๊น€์น˜๋ผ๋–ผ', 4500, 8, 'Y');
INSERT INTO tbl_menu VALUES (null, '์šฐ๋Ÿญ์Šค๋ฌด๋””', 5000, 10, 'Y');
INSERT INTO tbl_menu VALUES (null, '์ƒ๊ฐˆ์น˜์‰์ดํฌ', 6000, 10, 'Y');
INSERT INTO tbl_menu VALUES (null, '๊ฐˆ๋ฆญ๋ฏธ์—ญํŒŒ๋ฅดํŽ˜', 7000, 10, 'Y');
INSERT INTO tbl_menu VALUES (null, '์•™๋ฒ„ํ„ฐ๊น€์น˜์ฐœ', 13000, 4, 'N');

INSERT INTO tbl_menu VALUES (null, '์ƒ๋งˆ๋Š˜์ƒ๋Ÿฌ๋“œ', 12000, 4, 'Y');
INSERT INTO tbl_menu VALUES (null, '๋ฏผํŠธ๋ฏธ์—ญ๊ตญ', 15000, 4, 'Y');
INSERT INTO tbl_menu VALUES (null, 'ํ•œ์šฐ๋”ธ๊ธฐ๊ตญ๋ฐฅ', 20000, 4, 'Y');
INSERT INTO tbl_menu VALUES (null, 'ํ™์–ด๋งˆ์นด๋กฑ', 9000, 12, 'Y');
INSERT INTO tbl_menu VALUES (null, '์ฝ”๋‹ค๋ฆฌ๋งˆ๋Š˜๋นต', 7000, 12, 'N');

INSERT INTO tbl_menu VALUES (null, '์ •์–ด๋ฆฌ๋น™์ˆ˜', 10000, 10, 'Y');
INSERT INTO tbl_menu VALUES (null, '๋‚ ์น˜์•Œ์Šคํฌ๋ฅ˜๋ฐ”', 2000, 10, 'Y');
INSERT INTO tbl_menu VALUES (null, '์งํ™”๊ตฌ์ด์ ค๋ผ๋˜', 8000, 12, 'Y');
INSERT INTO tbl_menu VALUES (null, '๊ณผ๋ฉ”๊ธฐ์ปคํ‹€๋ฆฟ', 13000, 6, 'Y');
INSERT INTO tbl_menu VALUES (null, '์ฃฝ๋ฐฉ๋ฉธ์น˜ํŠ€๊น€์šฐ๋™', 11000, 6, 'N');

INSERT INTO tbl_menu VALUES (null, 'ํ‘๋งˆ๋Š˜์•„๋ฉ”๋ฆฌ์นด๋…ธ', 9000, 8, 'Y');
INSERT INTO tbl_menu VALUES (null, '์•„์ด์Šค๊ฐ€๋ฆฌ๋น„๊ด€์ž์œก์ˆ˜', 6000, 10, 'Y');
INSERT INTO tbl_menu VALUES (null, '๋ถ•์–ด๋นต์ดˆ๋ฐฅ', 35000, 6, 'Y');
INSERT INTO tbl_menu VALUES (null, '๊นŒ๋‚˜๋ฆฌ์ฝ”์ฝ”๋„›์ฅฌ์Šค', 9000, 9, 'Y');
INSERT INTO tbl_menu VALUES (null, '๋งˆ๋ผ๊น์‡ผํ•œ๋ผ๋ด‰', 22000, 5, 'N');

INSERT INTO tbl_menu VALUES (null, '๋Œ๋ฏธ๋‚˜๋ฆฌ๋ฐฑ์„ค๊ธฐ', 5000, 11, 'Y');

COMMIT;
profile
์—”์ง€๋‹ˆ์–ด๋กœ์˜ ์„ฑ์žฅ์ผ์ง€

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