# ๐ @์์ฝ - MySQL ์ ๋๋ก ๋ฐฐ์ฐ๊ธฐ (inflearn)
์ฐ์ mysql
8๋ฒ์ ์ ์ค์น (opens new window)ํด์ฃผ๊ณ , ์ค์น ๊ณผ์ ์์ custom
์ ์ ํํ์ฌ workbench
๊น์ง 8๋ฒ์ ์ผ๋ก ์ค์นํด์ค๋ค.
# Mysql ์ฌ์ฉ์
# mysql ์ ์
C:\Users\๊ด๋ฆฌ์>mysql -u root -p
Enter password: ************
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 8.0.29 MySQL Community Server - GPL
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
# ์ฌ์ฉ์ ์กฐํ
mysql> use mysql;
Database changed
mysql> select user, host from user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
4 rows in set (0.00 sec)
# ์ฌ์ฉ์ ์ถ๊ฐ/๊ถํ๋ถ์ฌ
create user
mysql> create user <user-name>@'<host>' identified by '<password>';
mysql> create user 'test1234'@'localhost' identified by 'test1234';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all privileges on test_database.* to test@'localhost';
Query OK, 0 rows affected (0.00 sec)
grant
mysql> grant all privileges on test_database.* to test_grant@'localhost' identified by 'test1234';
Query OK, 0 rows affected (0.00 sec)
localhost
๋์ ์ %
๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ธ๋ถ์์๋ ์ ์ ๊ฐ๋ฅํ๋ค
mysql> grant all privileges on test_database.* to test_grant@'%' identified by 'test1234';
Query OK, 0 rows affected (0.01 sec)
์ ์ฉํ๊ธฐ ํ์ !
mysql> flush privileges;
# ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ
mysql> use mysql;
Database changed
mysql> update user set password=PASSWORD('๋ณ๊ฒฝํ ๋น๋ฐ๋ฒํธ') where user='์ฌ์ฉ์์ด๋ฆ';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# ์ฌ์ฉ์ ์ญ์
mysql> delete from user where user='USER_ID';
mysql> flush privileges;
mysql> delete from user where user='test';
Query OK, 1 row affected (0.00 sec)
mysql> delete from user where user='test_grant';
Query OK, 2 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# database ์์ฑ
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database testdb;
Query OK, 1 row affected (0.02 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
# mysql workbench ์ฐ๊ฒฐ
# table ์์ฑ
#๋ถ์
create table Dept(
id tinyint unsigned not null auto_increment,
pid tinyint unsigned not null default 0 comment '์์๋ถ์id',
dname varchar(31) not null,
PRIMARY KEY(id)
);
#์ง์
create table Emp(
id int unsigned not null auto_increment,
ename varchar(31) not null,
dept tinyint unsigned not null,
salary int not null default 0 ,
primary key(id),
foreign key(dept) references Dept(id)
);
workbench
์์ refresh
ํด์ค์ผ ์์ฑ๋ ํ
์ด๋ธ ์กฐํ ๊ฐ๋ฅ
unsigned
๋ชจ๋ Integerํ์
๋ค์ UNSIGNED
๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
ํด๋น ์ปฌ๋ผ์ด ์์๊ฐ ์ ๋ ๋ ์ผ์ด ์๋ ๊ฒฝ์ฐ, (auto-increment๋ก primary key๋ฅผ ์ก์ ๋์ ๊ฐ์ด) ์์ ๋ฒ์๊ฐ ์์ ์ชฝ์ผ๋ก ๋ ๋์ผ๋ฉด ์ข์ ๊ฒ์ด๋ค.
์ด๋ ์ฌ์ฉํ๋ ๊ฒ unsigned
ํ์
์ด๋ค.
unsigned
์๋ ๋:-2147483648 ~ 2147483647
unsigned
์ผ ๋:0 ~ 4294967295
# select/insert
#์์๋ถ์
insert into Dept(pid, dname) values (0, '์์
๋ถ'), (0, '๊ฐ๋ฐ๋ถ');
#ํ์๋ถ์
insert into Dept(pid, dname)
values (1, '์์
1ํ'), (1, '์์
2ํ'), (1, '์์
3ํ'), (2, '์๋ฒํ'), (2, 'ํด๋ผ์ด์ธํธํ');
# inner join
# ์ ์ฒด์กฐํ
mysql> select * from Dept;
+----+-----+--------------+
| id | pid | dname |
+----+-----+--------------+
| 1 | 0 | ์์
๋ถ |
| 2 | 0 | ๊ฐ๋ฐ๋ถ |
| 3 | 1 | ์์
1ํ |
| 4 | 1 | ์์
2ํ |
| 5 | 1 | ์์
3ํ |
| 6 | 2 | ์๋ฒํ |
| 7 | 2 | ํด๋ผ์ด์ธํธํ |
+----+-----+--------------+
7 rows in set (0.00 sec)
# ํ์ ๋ถ์ ์กฐํ
mysql> select d1.dname as '์์๋ถ์', d2.* from Dept d1 inner join Dept d2 on d1.id = d2.pid;
+----------+----+-----+--------------+
| ์์๋ถ์ | id | pid | dname |
+----------+----+-----+--------------+
| ์์
๋ถ | 3 | 1 | ์์
1ํ |
| ์์
๋ถ | 4 | 1 | ์์
2ํ |
| ์์
๋ถ | 5 | 1 | ์์
3ํ |
| ๊ฐ๋ฐ๋ถ | 6 | 2 | ์๋ฒํ |
| ๊ฐ๋ฐ๋ถ | 7 | 2 | ํด๋ผ์ด์ธํธํ |
+----------+----+-----+--------------+
5 rows in set (0.00 sec)
rand()
- 0๊ณผ 1 ์ฌ์ด์ ๋์ ๋ฐ์
mysql> select rand();
+--------------------+
| rand() |
+--------------------+
| 0.3301079471875987 |
+--------------------+
1 row in set (0.00 sec)
- 0~10 ์ฌ์ด์ ๋์ ํ์ฌ ์ฌ๋ฆผ์ฒ๋ฆฌ (0์ด ๋์ค์ง ์๊ฒ ์ฌ๋ฆผ์ผ๋ก ์ฒ๋ฆฌ)
mysql> select CEIL(rand() * 10);
+-------------------+
| CEIL(rand() * 10) |
+-------------------+
| 3 |
+-------------------+
1 row in set (0.00 sec)
# function ์์ฑ
function ์์ฑ ์ ๋๋ ๊ฒฝ์ฐ
SET GLOBAL log_bin_trust_function_creators=ON;
# 1. ํ๊ธ์๋ฅผ ๋๋ค์ผ๋ก ๋ฐํํ๋ ํจ์๋ฅผ ๋ง๋ค์ด๋ณด์.
CREATE FUNCTION `f_rand1` (_str varchar(255)) -- ๋งค๊ฐ๋ณ์๋ _
RETURNS varchar(31)
BEGIN
declare v_ret varchar(31); -- ๋ณ์๋ v_
declare v_len tinyint;
set v_len = char_length(_str); -- ํ๊ธ์ 3๋ฐ์ดํธ์ด๋ฏ๋ก char_lengthํ๋ฉด ๊ธ์์๋๋ก ๊ธธ์ด ๋ฐํ
set v_ret = substring(_str, CEIL(rand() * v_len), 1); -- ๋จ์ด์์ 1๊ธ์๋ง ๋๋ค์ผ๋ก ๋ฐํ
RETURN v_ret;
END
mysql> select f_rand1('๊น์ด๋ฐ');
+-------------------+
| f_rand1('๊น์ด๋ฐ') |
+-------------------+
| ๊น |
+-------------------+
1 row in set (0.00 sec)
mysql> select f_rand1('1234567');
+--------------------+
| f_rand1('1234567') |
+--------------------+
| 7 |
+--------------------+
1 row in set (0.00 sec)
mysql> select f_rand1('1234567');
+--------------------+
| f_rand1('1234567') |
+--------------------+
| 3 |
+--------------------+
1 row in set (0.00 sec)
# 2. f_rand1
ํจ์๋ฅผ ํ์ฉํด์ ์ด๋ฆ์ ๋ง๋ค์ด์ฃผ๋ ํจ์๋ฅผ ๋ง๋ค์ด๋ณด์.
CREATE FUNCTION `f_randname` ()
RETURNS varchar(31)
BEGIN
declare v_ret varchar(31);
declare v_lasts varchar(255) default '๊น์ด๋ฐ์กฐ์ต์ ์ฒ๋ฐฉ์ง๋ง์ ๋ฐฐ์'; -- ์ฑ
declare v_firsts varchar(255) default '์์ ์ธ์ข
์ฑํธ์งํ๊ฐ์์ธํธ๋ฏผ๊ตญ๊ฐ๋๋ค๋ผ๋ง๋ฐ์ฌ์์์ฐจ๊ฒฐ์ฐฌ'; -- ์ด๋ฆ
set v_ret = concat(f_rand1(v_lasts), f_rand1(v_firsts), f_rand1(v_firsts));
RETURN v_ret;
END
mysql> select f_randname();
+--------------+
| f_randname() |
+--------------+
| ์ ๊ฒฐ์ |
+--------------+
1 row in set (0.00 sec)
mysql> select f_randname();
+--------------+
| f_randname() |
+--------------+
| ์๋คํธ |
+--------------+
1 row in set (0.00 sec)
# Procedure
# ์ฌ๋ฌ๋ช ์ ์ง์์ ํ๋ก์์ ๋ก ๋ฃ์ด๋ณด์.
ํ์๋ถ์์ ์ํ๊ธฐ ์ํด
CREATE PROCEDURE `sp_test_emp` (_cnt int)
BEGIN
declare v_idx int default 0;
while v_idx < _cnt
do
-- ํ์๋ถ์์ ์ํ๊ธฐ ์์ '34567', ๊ธ์ฌ๋ *100ํ์ฌ `100~900`๊น์ง
insert into Emp(ename, dept, salary) values (f_randname(), f_rand1('34567'), f_rand1('123456789') * 100);
set v_idx = v_idx + 1;
end while;
END
mysql> call sp_test_emp(10);
Query OK, 1 row affected (0.02 sec)
mysql> select * from emp;
+----+--------+------+--------+
| id | ename | dept | salary |
+----+--------+------+--------+
| 1 | ์ ์ฐจ์ข
| 7 | 100 |
| 2 | ๋ง๋ฏผ์ข
| 4 | 800 |
| 3 | ์กฐ์๋ผ | 6 | 500 |
| 4 | ์ตํธ์ | 5 | 400 |
| 5 | ์กฐ์ธํธ | 6 | 200 |
| 6 | ์ต๊ตญ์ธ | 5 | 200 |
| 7 | ์กฐ์ฐจ๋ง | 7 | 500 |
| 8 | ๋ฐฉ์ธ์ง | 3 | 700 |
| 9 | ์ ๊ฒฐ์ | 3 | 100 |
| 10 | ์ด์ธ์ฌ | 6 | 800 |
| 11 | ์ฒ๋ฐ๊ฐ | 5 | 300 |
| 12 | ์ ํ์ข
| 6 | 400 |
+----+--------+------+--------+
12 rows in set (0.00 sec)
# group by
# ๋ถ์๋ณ ์ง์ ์ ์กฐํ
mysql> select dept, count(*) from Emp group by dept;
+------+----------+
| dept | count(*) |
+------+----------+
| 3 | 62 |
| 4 | 47 |
| 5 | 47 |
| 6 | 55 |
| 7 | 51 |
+------+----------+
5 rows in set (0.00 sec)
# table ์ ๋ณด
mysql> desc Dept;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | tinyint unsigned | NO | PRI | NULL | auto_increment |
| pid | tinyint unsigned | NO | | 0 | |
| dname | varchar(31) | NO | | NULL | |
+-------+------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> show create table Dept;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Dept | CREATE TABLE `dept` (
`id` tinyint unsigned NOT NULL AUTO_INCREMENT,
`pid` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '์์๋ถ์id',
`dname` varchar(31) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> show index from Dept;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| dept | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | | YES | NULL |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.00 sec)
mysql> show index from Emp;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| emp | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | | YES | NULL |
| emp | 1 | dept | 1 | dept | A | 0 | NULL | NULL | | BTREE | | | YES | NULL |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.00 sec)
# table ๋ณต์
# ๋ฐ์ดํฐ๋นผ๊ณ ๊ตฌ์กฐ๋ง ๋ณต์
create table Dept2 like Dpet;
# ๋ฐ์ดํฐ๊น์ง ๋ณต์
create table Dept3 AS select * from Dept;
WARNING
index๋ ์ค์ ๋์ง ์๋๋ค..!
foriegn key์ ๊ฐ์ ์ค์ ์ ๋ณต์ ๋์ง ์์ผ๋ฏ๋ก ๋ฐ๋ก ์ค์ ํด์ฃผ์ด์ผ ํจ.
# table ์์
-- on update: ๋ฐ์ดํฐ ์์ ๋์๋ current_timestamp ์
๋ฐ์ดํธ
alter table Dept add column workdate timestamp not null default current_timestamp on update current_timestamp;
mysql> select * from Dept;
+----+-----+---------+---------------------+
| id | pid | dname | workdate |
+----+-----+---------+---------------------+
| 1 | 0 | ์์
๋ถ | 2022-04-27 14:17:46 |
| 2 | 0 | ๊ฐ๋ฐ๋ถ | 2022-04-27 14:17:46 |
| 3 | 1 | ์์
1ํ | 2022-04-27 14:17:46 |
| 4 | 1 | ์์
2ํ | 2022-04-27 14:17:46 |
| 5 | 1 | ์์
3ํ | 2022-04-27 14:17:46 |
| 6 | 2 | ์๋ฒํ | 2022-04-27 14:17:46 |
| 7 | 2 | ํด๋ผํ | 2022-04-27 14:18:06 |
+----+-----+---------+---------------------+
7 rows in set (0.00 sec)
# ์๋์ ๊ฐ์ด block์ฒ๋ฆฌํด์ ์์ ํ๋ ์ฐ์ตํ๊ธฐ
select * from Dept
-- update Dept set dname='ํด๋ผํ'
where id = 7;
# truncate ๊ณผ delete ์ฐจ์ด
truncate
์ ํ
์ด๋ธ์ ์ง์ ๋ค๊ฐ ๋ค์ ์์ฑํ๋ ๊ฑฐ๋ ๋ค๋ฆ ์๋ค. auto_increment๊ฐ 1๋ถํฐ ๋ค์ ์์ํ๋ค.
delete
ํด์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ฐ๋ฉด auto_increment๊ฐ ์ด์ ๊ฐ์์ +1 ๋๋ค.
# TCL: Commit & Rollback
WARNING
Session ๋จ์๋ก Tx๋ ์ ์ด๋จ.
# autocommit ํ์ธ
select @@autocommit;
-- ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ SET AUTOCOMMIT = FALSE;
# ์ฌ๋ฌ๊ฐ์ง ์์
์ ํ ๋, ๋ถ์ํ ๊ฒฝ์ฐ transcation
์ผ๋ก ์์
ํด์ค๋ค.
start transaction; -- transaction ์์
select * from Dept where id in (1,2);
update Dept set dname='์์
111' where id = 1;
commit; -- ์ ์ฉํ๊ณ ํ ๊ฒฝ์ฐ,
rollback; -- ์ทจ์ํ๊ณ ํ ๊ฒฝ์ฐ,
# savepoint
start transaction; -- transaction ์์
savepoint sp1; -- savepoint1 ์์
update Dept set dname='์์
111' where id = 1;
savepoint sp2; -- savepoint2 ์์
update Dept set dname='๊ฐ๋ฐ111' where id = 2;
rollback to savepoint sp2; --sp2 ๋ง ๋กค๋ฐฑ
commit; -- ์ ์ฉ (sp1๋ง ์ ์ฉ๋จ)
# View
View๋ฅผ ์ฌ์ฉํ๋ ์ด์
Security
๋ณด์์ ์ํด์
view
๋ฅผ ๋ง์ด ์ด๋ค. ํ ์ด๋ธ ํ ์ดํฐ๋ฅผ ์์ ํ์ง ๋ชปํ๋๋ก, ์ฌ์ฉ์ ์ ๊ทผ ๊ถํ์view
์กฐํ๋ง ๊ฐ๋ฅํ๋๋ก ํ๋ ๊ฒฝ์ฐ๊ฐ ์๋ค.Simplicity
๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ๋จ์ํ๊ฒ ํด์ค๋ค.
Performance
๋คํธ์ํฌ ํธ๋ํฝ์ด ์ค์ด๋ค๊ณ , ์ปดํ์ผํ๋ ์๊ฐ๋ ์ค์ด๋ ๋ค.
# ์์ฑ
์์ฑ ์ฟผ๋ฆฌ๋ ์๋์ ๊ฐ๊ณ , ์กฐํ๋ ํ
์ด๋ธ ์กฐํ์ ๋๊ฐ์ด select
๋ก ์กฐํํ๋ฉด ๋๋ค.
create view v_Emp AS
select e.*, d.dname from Emp e inner join Dept d on e.dept = d.id;
# view schema ์กฐํ
mysql> select * from information_schema.views where table_schema = 'testdb';
+---------------+--------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+--------------+----------------+---------------+----------------------+----------------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | VIEW_DEFINITION | CHECK_OPTION | IS_UPDATABLE | DEFINER | SECURITY_TYPE | CHARACTER_SET_CLIENT | COLLATION_CONNECTION |
+---------------+--------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+--------------+----------------+---------------+----------------------+----------------------+
| def | testdb | v_emp | select `e`.`id` AS `id`,`e`.`ename` AS `ename`,`e`.`dept` AS `dept`,`e`.`salary` AS `salary`,`d`.`dname` AS `dname` from (`testdb`.`emp` `e` join `testdb`.`dept` `d` on((`e`.`dept` = `d`.`id`))) | NONE | YES | root@localhost | DEFINER | utf8mb4 | utf8mb4_0900_ai_ci |
+---------------+--------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+--------------+----------------+---------------+----------------------+----------------------+
1 row in set (0.00 sec)
# Trigger
ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด ์ ์ ๋ก ์คํ๋๋ค.
DELIMITER //
Create Trigger <trigger-name>
{ BEFORE | AFTER } { INSERT | UPDATE | DELETE } -- ํน์ ์์
์ํ ์ /ํ (๋ณดํต ํ์ ๋ง์ด ํจ)
{ PRECEDES | FOLLOWS } other-trigger-name -- ๋ค๋ฅธ ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ ์๋๊ฒฝ์ฐ PRECEDES: otherํ๊ธฐ์ ์ ํ๋ผ / FOLLOWS: otherํ๊ณ ํ๋ผ
on <table-name> FOR EACH ROW
BEGIN
... OLD.<col> ... NEW.<col>; -- OLD: update์ด์ ๊ฐ / NEW: update์ดํ๊ฐ
END //
DELIMITER;
# ์ฐ์ ๊ธฐ์กด Dept
ํ
์ด๋ธ์ ์ง์ ์์ธ empcnt
์ปฌ๋ผ์ ์ถ๊ฐํด์ฃผ๊ณ , ํ์ฌ ์ง์์๋ก update
์ฒ๋ฆฌํด์ฃผ์.
alter table Dept add column empcnt int not null default 0;
update Dept d set empcnt = (select count(*) from Emp where dept = d.id);
# Trigger
๋ฅผ ์ ์ฉํด์ฃผ์.
CREATE DEFINER = CURRENT_USER TRIGGER `testdb`.`emp_AFTER_INSERT` AFTER INSERT ON `emp` FOR EACH ROW
BEGIN
update Dept set empcnt = empcnt + 1
where id = NEW.dept;
END
# insert
ํด๋ณด๋ฉด Trigger
๊ฐ ์ ์ฉ๋์ด empcnt
๊ฐ ๋์ด๋๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
mysql> select * from Dept;
+----+-----+---------+---------------------+---------+--------+
| id | pid | dname | workdate | captain | empcnt |
+----+-----+---------+---------------------+---------+--------+
| 1 | 0 | ์์
111 | 2022-04-27 16:58:13 | NULL | 0 |
| 2 | 0 | ๊ฐ๋ฐ๋ถ | 2022-04-27 16:57:39 | NULL | 0 |
| 3 | 1 | ์์
1ํ | 2022-04-28 10:23:20 | 66 | 62 |
| 4 | 1 | ์์
2ํ | 2022-04-28 10:23:20 | 198 | 47 |
| 5 | 1 | ์์
3ํ | 2022-04-28 13:52:15 | 76 | 48 |
| 6 | 2 | ์๋ฒํ | 2022-04-28 10:23:20 | NULL | 55 |
| 7 | 2 | ํด๋ผํ | 2022-04-28 10:23:20 | 259 | 51 |
+----+-----+---------+---------------------+---------+--------+
7 rows in set (0.01 sec)
mysql> insert into Emp(ename, dept, salary) values ('SSS', 5, 200);
Query OK, 1 row affected (0.01 sec)
mysql> select * from Dept;
+----+-----+---------+---------------------+---------+--------+
| id | pid | dname | workdate | captain | empcnt |
+----+-----+---------+---------------------+---------+--------+
| 1 | 0 | ์์
111 | 2022-04-27 16:58:13 | NULL | 0 |
| 2 | 0 | ๊ฐ๋ฐ๋ถ | 2022-04-27 16:57:39 | NULL | 0 |
| 3 | 1 | ์์
1ํ | 2022-04-28 10:23:20 | 66 | 62 |
| 4 | 1 | ์์
2ํ | 2022-04-28 10:23:20 | 198 | 47 |
| 5 | 1 | ์์
3ํ | 2022-04-28 13:53:11 | 76 | 49 |
| 6 | 2 | ์๋ฒํ | 2022-04-28 10:23:20 | NULL | 55 |
| 7 | 2 | ํด๋ผํ | 2022-04-28 10:23:20 | 259 | 51 |
+----+-----+---------+---------------------+---------+--------+
7 rows in set (0.00 sec)
# delete
์๋ empcnt
๊ฐ -1 ๋๋๋ก trigger๋ฅผ ๊ฑธ์ด์ค๋ค.
CREATE DEFINER = CURRENT_USER TRIGGER `testdb`.`emp_AFTER_DELETE` AFTER DELETE ON `emp` FOR EACH ROW
BEGIN
update Dept set empcnt = empcnt - 1
where id = OLD.dept; -- ์๋ก ๋ค์ด์ค๋ NEW๊ฐ ์์ผ๋ฏ๋ก OLD๋ก ์จ์ค๋ค.
END
# update
์๋ ๊ฑธ์ด์ค๋ค. dept
-์ํ ๋ถ์๊ฐ ์์ ๋๋ ๊ฒฝ์ฐ๋ empcnt
๋ฅผ ๋ณ๊ฒฝํด์ค์ผํ๋ค.
CREATE DEFINER=`root`@`localhost` TRIGGER `emp_AFTER_UPDATE` AFTER UPDATE ON `emp` FOR EACH ROW BEGIN
IF OLD.dept != NEW.dept THEN -- ๋ถ์๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ
update Dept set empcnt = empcnt - 1
where id = OLD.dept;
update Dept set empcnt = empcnt + 1
where id = NEW.dept;
END IF;
END
# UNION
# UNION
์ ์ค๋ณต์ ๋นผ๊ณ , UNION ALL
์ ์ค๋ณต๋ ํฌํจํ๋ค.
select * from subject where classroom < 3
{ UNION | UNION ALL}
select * from subject where classroom < 5
# @rownum
์๋ฒ์ ๋งค๊ธฐ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
mysql> select s.*, (@rownum := @rownum + 1)from Emp s, (select @rownum := 0) rn;
+-----+--------+------+--------+--------------------------+
| id | ename | dept | salary | (@rownum := @rownum + 1) |
+-----+--------+------+--------+--------------------------+
| 1 | ์ ์ฐจ์ข
| 7 | 100 | 1 |
| 2 | ๋ง๋ฏผ์ข
| 4 | 800 | 2 |
| 3 | ์กฐ์๋ผ | 6 | 500 | 3 |
| 4 | ์ตํธ์ | 5 | 400 | 4 |
| 5 | ์กฐ์ธํธ | 6 | 200 | 5 |
| 6 | ์ต๊ตญ์ธ | 5 | 200 | 6 |
| 7 | ์กฐ์ฐจ๋ง | 7 | 500 | 7 |
| 8 | ๋ฐฉ์ธ์ง | 3 | 700 | 8 |
| 9 | ์ ๊ฒฐ์ | 3 | 100 | 9 |
| 10 | ์ด์ธ์ฌ | 6 | 800 | 10 |
| 11 | ์ฒ๋ฐ๊ฐ | 5 | 300 | 11 |
| 12 | ์ ํ์ข
| 6 | 400 | 12 |
| 13 | ์ฒ๊ฐํธ | 3 | 100 | 13 |
| 14 | ์ ์ฐจ์ | 5 | 300 | 14 |
| 15 | ์ ๊ฐ์ข
| 6 | 100 | 15 |
| 16 | ์ ์ฌ๋ฐ | 4 | 400 | 16 |
| 17 | ๊น์ฐฌ์ | 3 | 100 | 17 |
| 18 | ์๊ฐ์ฐฌ | 4 | 300 | 18 |
| 19 | ๋ง์๊ฒฐ | 3 | 200 | 19 |
...์๋ต
# Procudure - OUT ์ถ๋ ฅ | into ์ฌ์ฉ
# ํ๋ก์์ ์์
ํ, ๋ณ์๋ฅผ ์ถ๋ ฅํ๊ณ ์ถ์ ๋ OUT
์ ์ฌ์ฉํ๋ค.
CREATE PROCEDURE `sp_emp_del`(_empid int, OUT _empcnt int) -- ์ญ์ ํ, empcnt ๊ฐ์ ธ์ค๊ณ ์ถ์๋
BEGIN
declare v_deptid tinyint;
select dept into v_deptid from Emp where id = _empid; -- into: dept๋ฅผ v_deptid ๋ณ์์ ์
๋ ฅ
delete from Emp where id = _empid;
select empcnt into _empcnt from Dept where id = v_deptid;
END
call sp_emp_del(6, @empcnt); -- empcnt๋ฅผ ๋ฐ์์จ๋ค.
select @empcnt;
Leave
Leave
๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ก์์ ๋์ค ์ค๋จ ๊ฐ๋ฅํ๋ค.
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_emp_range`(_sid int, _eid int)
prox:BEGIN
... ์๋ต
leave prox; -- ์กฐ๊ฑด ๋ง์กฑ ๋ชปํ์ ๋, ์ทจ์์ํค๊ณ ์ถ์ ๊ฒฝ์ฐ
END
# Prepare
# String์ผ๋ก ๋ฐ์์จ ๊ฐ ์ฟผ๋ฆฌ์ ์ฌ์ฉํ๊ธฐ
CREATE PROCEDURE `sp_count`(_table varchar(31))
BEGIN
SET @sql = CONCAT('select count(*) cnt from ', _table);
PREPARE myQuery from @sql;
EXECUTE myQuery;
DEALLOCATE PREPARE myQuery; -- ๋ฉ๋ชจ๋ฆฌ์์ ์ญ์
END
# Cursor
# row๋ฅผ ์ ํํ๋ ๊ฐ๋ ์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
Declare <cursor-name> CURSOR FOR
select ....
Declare Continue Handler
For Not Found SET <end-flag> := True;
OPEN <cursor-name>;
<cursor-loop-var>: LOOP
Fetch <cursor-name> into <var-name>, ...;
IF <end-flag> THEN
LEAVE <cursor-loop-var>;
END IF;
...
END LOOP <cursor-loop-var>;
CLOSE <cursor-name>;
# Exception Handling
START TRANSACTION
DECLARE {EXIT | CONTINUE} HANDLER FOR [ SQLEXCEPTION | <code> ]
BEGIN
SHOW ERRORS;
SELECT '์๋ฌ๋ฐ์' as 'Result';
ROLLBACK;
END;
-- ์์์ CONTINUE ๋ผ๊ณ ์ ์ธํ๋ค๋ฉด, ์ค๋ฅ ๋ฐ์ํด๋ ์๋ ๊ณ์ ์ํ!
COMMIT;
# ์ ๋์จ ๋ด์ฉ์ ์ ๋ถ ์ฌ์ฉํ Procedure ์์
CREATE PROCEDURE `sp_emp_range`(_sid int, _eid int)
prox:BEGIN
declare v_sid int default _sid;
declare v_eid int default _eid;
-- cursor ์์ ๋ณ์
declare v_empid int;
declare v_ename varchar(31);
declare v_dname varchar(31);
-- cursor ์ข
๋ฃ flag
Declare _done boolean default False;
Declare _cur CURSOR FOR
select id, ename, dname from v_Emp where id between v_sid and v_eid;
Declare Continue Handler
For Not Found SET _done := True;
-- error handling
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SHOW ERRORS;
SELECT '์๋ฌ๋ฐ์' as 'Result';
END;
IF _sid < 0 AND _eid < 0 THEN
leave prox;
END IF;
IF _sid > _eid THEN
set v_sid = _eid;
set v_eid = _sid;
END IF;
-- ์์ํ
์ด๋ธ ์กด์ฌํ๋ ๊ฒฝ์ฐ drop
drop temporary table IF Exists Tmp;
-- ์์ ํ
์ด๋ธ ์์ฑ
create temporary table Tmp (
empid int,
edname varchar(63)
);
OPEN _cur; -- ์ปค์ ์ด๊ธฐ
cur_loop: LOOP
Fetch _cur into v_empid, v_ename, v_dname;
IF _done THEN
LEAVE cur_loop;
END IF;
insert into Tmp(empid, edname) values(v_empid, concat(v_ename, '-', ifnull(v_dname,'์์ํ์์')));
END LOOP cur_loop;
CLOSE _cur; -- ์ปค์ ๋ซ๊ธฐ
select * from Tmp;
END
mysql> call sp_emp_range(5,1);
+-------+----------------+
| empid | edname |
+-------+----------------+
| 1 | ์ ์ฐจ์ข
-ํด๋ผํ |
| 2 | ๋ง๋ฏผ์ข
-์์
2ํ |
| 3 | ์กฐ์๋ผ-์๋ฒํ |
| 4 | ์ตํธ์-์์
3ํ |
| 5 | ์กฐ์ธํธ-์๋ฒํ |
+-------+----------------+
5 rows in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
# WITH CTE
WITH - CTE
๋ฉ๋ชจ๋ฆฌ์ ์์ ๊ฒฐ๊ณผ ์ ์ผ๋ก ์ฌ๋ ค๋๊ณ ์ฌ์ฌ์ฉ. (cf. View, Function)
- ์ฅ์
์์์ ์ํ ์ ์ฐจ์ ์ผ๋ก ์์ฑ -> ์์ฑํ๊ธฐ ์ฝ๊ณ ์ฝ๊ธฐ ์ฝ๋ค.
WITH [RECURSIVE]
cte_name [(colr_name [, col_name] ...)] AS (subquery)
[, cte_name [(colr_name [, col_name] ...)] AS (subquery)]
select * from cte_name;
MY SQL์ CTE์๋ ์๋์ ๊ฐ์ด 2๊ฐ์ง CTE๋ฅผ ์ ๊ณตํ๊ณ ์๋ค.
1. Common Table Expressions (๊ธฐ๋ณธ CTE) - ์์ฐจ์ ์ผ๋ก ์ฟผ๋ฆฌ ์์ฑ ๊ฐ๋ฅ
2. Recursive Common Table Expressions (์ฌ๊ท CTE) - ์ค์ค๋ก ์ถ๊ฐ์ ์ธ Row๋ฅผ ์์ฑํ ์ ์๋ค.
WITH
AvgSal AS ( -- ํ๊ท ๊ธ์ฌ
select d.dname, avg(e.salary) avgsal
from Dept d inner join Emp e on d.id = e.dept
group by d.id
),
MaxAvgSal AS ( -- ์ต๊ณ
select * from AvgSal order by avgSal desc limit 1
),
MinAvgSal AS ( -- ์ต์
select * from AvgSal order by avgSal asc limit 1
),
SumUp AS ( -- union
select '์ต๊ณ ' as gb, m1.* from MaxAvgSal m1
UNION
select '์ต์ ' as gb, m2.* from MinAvgSal m2
)
select * from Sumup
UNION
select '', 'ํ๊ท ๊ธ์ฌ์ฐจ์ก', format((max(avgsal) - min(avgsal))* 10000, 0) from SumUp; -- ์ฐจ์ก
+------+--------------+----------+
| gb | dname | avgsal |
+------+--------------+----------+
| ์ต๊ณ | ์๋ฒํ | 538.1818 |
| ์ต์ | ์์
3ํ | 450.0000 |
| | ํ๊ท ๊ธ์ฌ์ฐจ์ก | 881,818 |
+------+--------------+----------+
3 rows in set (0.00 sec)
# ์ฌ๊ท CTE
# ํผ๋ณด๋์น ์์ด
๋ณ์์ ๋ง์ถฐ์ ์กฐํํด์ผ ํ๋ค.
WITH RECURSIVE fibonacci (n, fib_n, next_fib_n) AS -- ๋ณ์ 3๊ฐ
(
select 1, 0, 1 -- 3๊ฐ
UNION ALL
select n + 1, next_fib_n, fib_n + next_fib_n -- 3๊ฐ
from fibonacci where n < 10
)
select * from fibonacci;
+------+-------+------------+
| n | fib_n | next_fib_n |
+------+-------+------------+
| 1 | 0 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 2 |
| 4 | 2 | 3 |
| 5 | 3 | 5 |
| 6 | 5 | 8 |
| 7 | 8 | 13 |
| 8 | 13 | 21 |
| 9 | 21 | 34 |
| 10 | 34 | 55 |
+------+-------+------------+
10 rows in set (0.00 sec)
# ๊ณ์ธต ํ ์คํธ๋ฅผ ์ํด ๋ถ์๋ฅผ ๋ฃ์ด์ฃผ์
insert into Dept(pid, dname) values(6, '์ธํ๋ผ์
');
insert into Dept(pid, dname) values(6, 'DB์
');
insert into Dept(pid, dname) values(7, '๋ชจ๋ฐ์ผ์
');
# ์ฐ์ ํธ๋ฆฌ๊ตฌ์กฐ๊ฐ ์๋ ํํ๋ก ์กฐํ
WITH RECURSIVE CteDept (id, pid, npname, dname, d) AS -- d: depth : ์คํ์์
(
select id, pid, cast('' as char(31)), dname, 0 from Dept where pid = 0
UNION ALL
select d.id, d.pid, cte.dname, d.dname, d + 1 from Dept d inner join CteDept cte on d.pid = cte.id
)
select * from CteDept;
+------+------+--------+----------+------+
| id | pid | npname | dname | d |
+------+------+--------+----------+------+
| 1 | 0 | | ์์
๋ถ | 0 |
| 2 | 0 | | ๊ฐ๋ฐ๋ถ | 0 |
| 3 | 1 | ์์
๋ถ | ์์
1ํ | 1 |
| 4 | 1 | ์์
๋ถ | ์์
2ํ | 1 |
| 5 | 1 | ์์
๋ถ | ์์
3ํ | 1 |
| 6 | 2 | ๊ฐ๋ฐ๋ถ | ์๋ฒํ | 1 |
| 7 | 2 | ๊ฐ๋ฐ๋ถ | ํด๋ผํ | 1 |
| 9 | 6 | ์๋ฒํ | ์ธํ๋ผ์
| 2 |
| 10 | 6 | ์๋ฒํ | DB์
| 2 |
| 11 | 7 | ํด๋ผํ | ๋ชจ๋ฐ์ผ์
| 2 |
+------+------+--------+----------+------+
10 rows in set (0.00 sec)
# ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ์กฐํ
WITH RECURSIVE CteDept (id, pid, npname, dname, d, h) AS
(
select id, pid, cast('' as char(31)), dname, 0, cast(id as char(10)) from Dept where pid = 0
UNION ALL
select d.id, d.pid, cte.dname, d.dname, d + 1, concat(cte.h, '-', d.id) from Dept d inner join CteDept cte on d.pid = cte.id
)
select * from CteDept order by h;
+------+------+--------+----------+------+--------+
| id | pid | npname | dname | d | h |
+------+------+--------+----------+------+--------+
| 1 | 0 | | ์์
๋ถ | 0 | 1 |
| 3 | 1 | ์์
๋ถ | ์์
1ํ | 1 | 1-3 |
| 4 | 1 | ์์
๋ถ | ์์
2ํ | 1 | 1-4 |
| 5 | 1 | ์์
๋ถ | ์์
3ํ | 1 | 1-5 |
| 2 | 0 | | ๊ฐ๋ฐ๋ถ | 0 | 2 |
| 6 | 2 | ๊ฐ๋ฐ๋ถ | ์๋ฒํ | 1 | 2-6 |
| 10 | 6 | ์๋ฒํ | DB์
| 2 | 2-6-10 |
| 9 | 6 | ์๋ฒํ | ์ธํ๋ผ์
| 2 | 2-6-9 |
| 7 | 2 | ๊ฐ๋ฐ๋ถ | ํด๋ผํ | 1 | 2-7 |
| 11 | 7 | ํด๋ผํ | ๋ชจ๋ฐ์ผ์
| 2 | 2-7-11 |
+------+------+--------+----------+------+--------+
10 rows in set (0.00 sec)
# ์ฌ๊ท ํ์ ์ ํํ๊ธฐ
session์ผ๋ก ํ์ ์ ํ
SET SESSION cte_max_recursion_depth = 20; -- ์ฌ๊ท ์คํ ์ ํ
WITH RECURSIVE cte (n) AS
(
SELECT 1
UNION ALL
SELECT n + 1 FROM cte -- limit 21 ๊น์ง ๊ฐ๋ฅ
)
SELECT * FROM cte;
-- 20๋ฒ ์ด์ ์คํ๋๊ธฐ๋๋ฌธ์ ๋ฃจํ์ ๋น ์ง์ง ์๋๋ก ์๋ฌ๊ฐ ๋ฐ์๋๋ค.
์ฃผ์ ํํธ๋ก ์ ํ
SET SESSION cte_max_recursion_depth = 20; -- ์ฌ๊ท ์คํ ์ ํ
WITH RECURSIVE cte (n) AS
(
SELECT 1
UNION ALL
SELECT n + 1 FROM cte limit 21
)
SELECT /*+ SET_VAR(cte_max_recursion_depth = 10) */ * FROM cte; -- HINT! ์์ session๋ณด๋ค ์ฐ์ ..
-- 11๋ฒ ๊น์ง๋ง ๊ฐ๋ฅํ๋ค๊ณ ์๋ฌ๊ฐ ๋ฐ์๋จ.
# ์๋์ฐ ํจ์
# windowFunc() over(PARTITION BY ๊ทธ๋ฃน ORDER BY ์ ๋ ฌ๊ธฐ์ค) ์ด๋ ๊ฒ ์ฌ์ฉํ๋ค.
Window Function - 1
ํจ์ | ์ค๋ช |
---|---|
ROW_NUMBER() | ์ ์ฒด ๊ฒฐ๊ณผ์์ ํํฐ์ ๊ธฐ์ค ์ถ๋ ฅ๋๋ ํ ๋ฒํธ(์๋ฒ) |
RANK() | ๊ฐ์ ๋ญํน(์์), ๊ณต๋ ๋ญํน์ ๋์ผ๊ฐ์ ๋ณด์ด๋ฉฐ ๋ค์ ๋ญํน์ ๊ณต๋ ๋ญํน์ ๊ฑด๋๋ฐ์ด ํ์ |
DESNE_RANK() | RANK() ํจ์์ ๋์ผํ ๊ธฐ๋ฅ์ด์ง๋ง ๊ณต๋ ๋ญํน์ ๊ฑด๋๋ฐ์ง ์๋๋ค. |
PERCENT_RANK() | ๋ญํน์ ๋ฐฑ๋ถ์จ๋ก ๋ํ๋ธ๋ค. ํํฐ์ ๋ด์์ ์์นํ๋ ๋ญํน์ %. |
CUME_DIST() | ํํฐ์ ๋ด ์ฐจ์ง ํ๋ ์์น๋ฅผ ๋์ (cumulative)๋ ๊ฑฐ๋ฆฌ๋ฅผ %๋ก ๋ํ๋ด์ด ๊ทธ๋ํ๋ฅผ ๊ทธ๋ฆฐ๋ค๋ฉด ๊ฒฝ๊ณ(outbound)๋ฅผ ๋ํ๋ธ๋ค. |
NTILE(n) | ํํฐ์ ๋ด ๋ก์ฐ๋ค์ n ๊ฐ์ ๊ทธ๋ฃน์ผ๋ก ๋๋ด์ ๋ ๊ทธ๋ฃน ๋ฒํธ. ๋ณดํต ์์์ ๋ง์ถฐ ๊ทธ๋ฃน(์์ญ)์ ๋๋ ๋ ์ฌ์ฉ |
Window Function - 2
ํจ์ | ์ค๋ช |
---|---|
FIRST_VALUE(col) | ํํฐ์ ๋ด ์ฒซ๋ฒ์งธ col ์ปฌ๋ผ์ ๊ฐ |
LAST_VALUE(col) | ํํฐ์ ๋ด ๋ง์ง๋ง col ์ปฌ๋ผ์ ๊ฐ |
NTH_VALUE(col, n) | ํํฐ์ ๋ด n๋ฒ์งธ col ์ปฌ๋ผ์ ๊ฐ |
LAG(n) | ํ์ฌ ํ ๊ธฐ์ค ์(์ด์ ) n ๋ฒ์งธ ๊ฐ |
LEAD(n) | ํ์ฌ ํ ๊ธฐ์ค ๋ค(๋ค์) n ๋ฒ์งธ ๊ฐ |
select row_number() over(order by dept, salary desc) '์๋ฒ',
e.*,
rank() over w '๋ถ์๋ด ์์',
dense_rank() over w '๋ถ์๋ด ์์',
percent_rank() over w '๋ถ์๋ด %์์',
cume_dist() over w '๋ถ์๋ด %๊ฒฝ๊ณ',
ntile(3) over w '๊ธ์ฌ๋ฑ๊ธ'
from Emp e
where ename like '๋ฐ%'
WINDOW w as (partition by dept order by dept, salary desc) -- ์ด๊ฑธ ์จ์ฃผ๋ฉด over()๋ฅผ ์จ์ฃผ์ง ์์๋ ๋๋ค.
;
+------+-----+--------+------+--------+-------------+-------------+--------------------+---------------------+----------+
| ์๋ฒ | id | ename | dept | salary | ๋ถ์๋ด ์์ | ๋ถ์๋ด ์์ | ๋ถ์๋ด %์์ | ๋ถ์๋ด %๊ฒฝ๊ณ | ๊ธ์ฌ๋ฑ๊ธ |
+------+-----+--------+------+--------+-------------+-------------+--------------------+---------------------+----------+
| 1 | 169 | ๋ฐ๊ตญ๊ฒฐ | 3 | 900 | 1 | 1 | 0 | 0.3333333333333333 | 1 |
| 2 | 105 | ๋ฐํธ๋ง | 3 | 700 | 2 | 2 | 0.5 | 0.6666666666666666 | 2 |
| 3 | 137 | ๋ฐ์๋ค | 3 | 400 | 3 | 3 | 1 | 1 | 3 |
| 4 | 147 | ๋ฐ์ธ์ฐจ | 4 | 900 | 1 | 1 | 0 | 0.25 | 1 |
| 5 | 145 | ๋ฐ๋ฏผ๋ง | 4 | 800 | 2 | 2 | 0.3333333333333333 | 0.5 | 1 |
| 6 | 82 | ๋ฐ์ฌ๊ฐ | 4 | 700 | 3 | 3 | 0.6666666666666666 | 1 | 2 |
| 7 | 237 | ๋ฐ๋ฏผ์ฌ | 4 | 700 | 3 | 3 | 0.6666666666666666 | 1 | 3 |
| 8 | 143 | ๋ฐ๋ค๋ง | 5 | 700 | 1 | 1 | 0 | 0.5 | 1 |
| 9 | 165 | ๋ฐ์๊ตญ | 5 | 300 | 2 | 2 | 1 | 1 | 2 |
| 10 | 43 | ๋ฐ์๋ค | 6 | 900 | 1 | 1 | 0 | 0.3333333333333333 | 1 |
| 11 | 44 | ๋ฐ์ข
์ง | 6 | 900 | 1 | 1 | 0 | 0.3333333333333333 | 1 |
| 12 | 71 | ๋ฐํธ๋ฏผ | 6 | 800 | 3 | 2 | 0.4 | 0.5 | 2 |
| 13 | 241 | ๋ฐ๋ง์ฐฌ | 6 | 700 | 4 | 3 | 0.6 | 0.6666666666666666 | 2 |
| 14 | 93 | ๋ฐ๋ฐํธ | 6 | 300 | 5 | 4 | 0.8 | 0.8333333333333334 | 3 |
| 15 | 114 | ๋ฐ๊ตญ์ | 6 | 100 | 6 | 5 | 1 | 1 | 3 |
| 16 | 49 | ๋ฐ์ ๋ค | 7 | 900 | 1 | 1 | 0 | 0.16666666666666666 | 1 |
| 17 | 223 | ๋ฐ์ฐจ๊ฒฐ | 7 | 800 | 2 | 2 | 0.2 | 0.3333333333333333 | 1 |
| 18 | 47 | ๋ฐ๋ฏผ์ | 7 | 600 | 3 | 3 | 0.4 | 0.5 | 2 |
| 19 | 37 | ๋ฐ์๋ง | 7 | 500 | 4 | 4 | 0.6 | 0.6666666666666666 | 2 |
| 20 | 21 | ๋ฐ๊ตญ์ธ | 7 | 200 | 5 | 5 | 0.8 | 1 | 3 |
| 21 | 238 | ๋ฐ์ฐจ๊ฒฐ | 7 | 200 | 5 | 5 | 0.8 | 1 | 3 |
+------+-----+--------+------+--------+-------------+-------------+--------------------+---------------------+----------+
21 rows in set (0.00 sec)
select row_number() over(order by dept, salary desc) '์๋ฒ',
e.*,
sum(salary) over w '๊ธ์ฌ ๋์ ์น',
first_value(salary) over w '๋ถ์๋ด 1๋ฑ ๊ธ์ฌ',
last_value(salary) over w '๋ถ์๋ด ํ์ฌ๊น์ง์ ๊ผด๋ฑ ๊ธ์ฌ',
nth_value(salary, 2) over w '๋ถ์๋ด 2๋ฑ ๊ธ์ฌ',
lag(salary, 1) over w '์ด์ ๊ธ์ฌ',
lead(salary, 1) over w '๋ค์ ๊ธ์ฌ'
from Emp e
where ename like '๋ฐ%'
WINDOW w as (partition by dept order by dept, salary desc) -- ์ด๊ฑธ ์จ์ฃผ๋ฉด over()๋ฅผ ์จ์ฃผ์ง ์์๋ ๋๋ค.
;
+------+-----+--------+------+--------+-------------+-----------------+-----------------------------+-----------------+-----------+-----------+
| ์๋ฒ | id | ename | dept | salary | ๊ธ์ฌ ๋์ ์น | ๋ถ์๋ด 1๋ฑ ๊ธ์ฌ | ๋ถ์๋ด ํ์ฌ๊น์ง์ ๊ผด๋ฑ ๊ธ์ฌ | ๋ถ์๋ด 2๋ฑ ๊ธ์ฌ | ์ด์ ๊ธ์ฌ | ๋ค์ ๊ธ์ฌ |
+------+-----+--------+------+--------+-------------+-----------------+-----------------------------+-----------------+-----------+-----------+
| 1 | 169 | ๋ฐ๊ตญ๊ฒฐ | 3 | 900 | 900 | 900 | 900 | NULL | NULL | 700 |
| 2 | 105 | ๋ฐํธ๋ง | 3 | 700 | 1600 | 900 | 700 | 700 | 900 | 400 |
| 3 | 137 | ๋ฐ์๋ค | 3 | 400 | 2000 | 900 | 400 | 700 | 700 | NULL |
| 4 | 147 | ๋ฐ์ธ์ฐจ | 4 | 900 | 900 | 900 | 900 | NULL | NULL | 800 |
| 5 | 145 | ๋ฐ๋ฏผ๋ง | 4 | 800 | 1700 | 900 | 800 | 800 | 900 | 700 |
| 6 | 82 | ๋ฐ์ฌ๊ฐ | 4 | 700 | 3100 | 900 | 700 | 800 | 800 | 700 |
| 7 | 237 | ๋ฐ๋ฏผ์ฌ | 4 | 700 | 3100 | 900 | 700 | 800 | 700 | NULL |
| 8 | 143 | ๋ฐ๋ค๋ง | 5 | 700 | 700 | 700 | 700 | NULL | NULL | 300 |
| 9 | 165 | ๋ฐ์๊ตญ | 5 | 300 | 1000 | 700 | 300 | 300 | 700 | NULL |
| 10 | 43 | ๋ฐ์๋ค | 6 | 900 | 1800 | 900 | 900 | 900 | NULL | 900 |
| 11 | 44 | ๋ฐ์ข
์ง | 6 | 900 | 1800 | 900 | 900 | 900 | 900 | 800 |
| 12 | 71 | ๋ฐํธ๋ฏผ | 6 | 800 | 2600 | 900 | 800 | 900 | 900 | 700 |
| 13 | 241 | ๋ฐ๋ง์ฐฌ | 6 | 700 | 3300 | 900 | 700 | 900 | 800 | 300 |
| 14 | 93 | ๋ฐ๋ฐํธ | 6 | 300 | 3600 | 900 | 300 | 900 | 700 | 100 |
| 15 | 114 | ๋ฐ๊ตญ์ | 6 | 100 | 3700 | 900 | 100 | 900 | 300 | NULL |
| 16 | 49 | ๋ฐ์ ๋ค | 7 | 900 | 900 | 900 | 900 | NULL | NULL | 800 |
| 17 | 223 | ๋ฐ์ฐจ๊ฒฐ | 7 | 800 | 1700 | 900 | 800 | 800 | 900 | 600 |
| 18 | 47 | ๋ฐ๋ฏผ์ | 7 | 600 | 2300 | 900 | 600 | 800 | 800 | 500 |
| 19 | 37 | ๋ฐ์๋ง | 7 | 500 | 2800 | 900 | 500 | 800 | 600 | 200 |
| 20 | 21 | ๋ฐ๊ตญ์ธ | 7 | 200 | 3200 | 900 | 200 | 800 | 500 | 200 |
| 21 | 238 | ๋ฐ์ฐจ๊ฒฐ | 7 | 200 | 3200 | 900 | 200 | 800 | 200 | NULL |
+------+-----+--------+------+--------+-------------+-----------------+-----------------------------+-----------------+-----------+-----------+
21 rows in set (0.00 sec)
# JSON ๋ฐ์ดํฐ ๋ค๋ฃจ๊ธฐ
JSON ํจ์ | ์ค๋ช |
---|---|
JSON_VALID() | ๋ฐ์ดํฐ์ ์ ํจ์ฑ ๊ฒ์ฌ |
JSON_PRETTY() | ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ํฌํจํด ๋ณด๊ธฐ ์ข๊ฒ JSON ๋ฐ์ดํฐ ์ถ๋ ฅ |
JSON_OBJECT() | ๋ฌธ์์ด ํํ๊ฐ ์๋ key, value ์์ผ๋ก JSON ๋ฐ์ดํฐ ๋ง๋ค๊ธฐ |
JSON_ARRAY() | JSON ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์ด(Array) ํํ๋ก ์์ฑ ๋ฐ ๋ณํ |
JSON_EXTRACT() | ์ธ๋ผ์ธ ํจ์ค(->)์ ๊ฐ์ด ํน์ ๊ฐ๋ง ๋ฝ์ ์ถ์ถ |
JSON_VALUE() | ํน์ ๊ฐ ์ถ์ถ, ์ถ๋ ฅ ํ์ ์ ์ ๊ฐ๋ฅ |
JSON_QUOTE() | ํน์ ๊ฐ ์ถ์ถ์ ๊ฐ์ ์ข์ฐ์ ํฐ๋ฐ์ดํ ๋ถ์ฌ์ ์ถ๋ ฅ |
JSON_UNQUOTE() | ํน์ ๊ฐ ์ถ์ถ์ ๊ฐ์ ์ข์ฐ์ ์ถ๋ ฅ๋๋ ํฐ๋ฐ์ดํ ์ ๊ฑฐ |
JSON_LENGTH() | JSON ๋ฐ์ดํฐ์ ํค ๊ฐ์ |
JSON_DEPTH() | JSON ๋ฐ์ดํฐ์ ๊น์ด(๊ณ์ธต) |
JSON_KEYS() | JSON ๋ฐ์ดํฐ์ key๋ค๋ง ์ถ์ถ |
JSON_TYPE() | JSON ๋ฐ์ดํฐ์ ๋ฐ์ดํฐ ํ์ ์ถ๋ ฅ |
JSON_SEARCH() | ํน์ ๊ฐ์ผ๋ก JSON ํจ์ค(์์น) ๊ฒ์ |
JSON_CONTAINS() | JSON ๋ฐ์ดํฐ์ ํน์ ๊ฐ์ ์กด์ฌ ์ฌ๋ถ ํ์ธ |
JSON_REPLACE() | JSON ๋ฐ์ดํฐ์ ๊ฐ ๋ถ๋ถ ๋ณ๊ฒฝ |
JSON_INSERT() | JSON ๋ฐ์ดํฐ์ ํน์ key, value ์์ ์ถ๊ฐ |
JSON_SET() | JSON ๋ฐ์ดํฐ์์ ํน์ key์ ํด๋น๋๋ ๊ฐ๋ง ๋ณ๊ฒฝ |
JSON_REMOVE() | JSON ๋ฐ์ดํฐ์ ํน์ key, value ์ ๊ฑฐ |
JSON_MERGE() | ๊ธฐ์กด JSON ๋ฐ์ดํฐ์ ๊ฐ ์ถ๊ฐ, MySQL 8์์ deprecated๋จ |
JSON_MERGE_PRESERVE() | JSON ๋ฐ์ดํฐ ํน์ ์์น์ ๊ฐ ๋ณ๊ฒฝ(๊ธฐ์กด ๊ฐ ์ ์ง) |
JSON_MERGE_PATCH() | JSON ๋ฐ์ดํฐ ํน์ ์์น์ ๊ฐ ๋ณ๊ฒฝ(๊ธฐ์กด ๊ฐ ๋์น) |
JSON_TABLE() | JSON ๋ฐ์ดํฐ๋ฅผ ํ ์ด๋ธ ํํ๋ก ์ ์ |
JSON_ARRAYAGG() | ์ ์ฒด JSON ๋ฐ์ดํฐ๋ฅผ ์ทจํฉ(ํตํฉ)ํ์ฌ ๋ฐฐ์ด๋ก ์ถ๋ ฅ |
JSON_OBJECTAGG() | JSON ๋ฐ์ดํฐ๋ฅผ ์ทจํฉ(ํตํฉ)ํ์ฌ Object ํํ๋ก ์ถ๋ ฅ |
JSON_STORAGE_SIZE() | JSON ๋ฐ์ดํฐ๊ฐ ์ฐจ์งํ๋ ๋ฐ์ดํฐ ํฌ๊ธฐ |
JSON_STORAGE_FREE() | JSON ๋ฐ์ดํฐ ์ปฌ๋ผ์ ์ฌ์ ๊ณต๊ฐ, JSON ๋ฐ์ดํฐ ์์ผ๋ฉด ํญ์ 0 |
alter table Emp add column remark JSON;
desc Emp;
update Emp set remark = '{ "addr": "์์ธ"}'
where id = 1;
update Emp set remark = '{"addr": "๋ถ์ฐ", "age": 39}'
where id = 2;
update Emp set remark = '{"addr": "๋๊ตฌ", "age": 29, "family": [ {"name": "๋
ผ๊ฐ", "relation": "๋ชจ"} ]}'
where id = 3;
update Emp set remark = '{"addr": "๊ฐ์", "age": 49, "family": [ {"name": "์กฐ์กฐ", "relation": "๋ถ"}, {"name": "๋ฐฐ์ฒ ๊ท ", "relation": "๋ชจ"} ]}'
where id = 4;
update Emp set remark = '{"addr": "์์ธ", "addr": "๋์ "}'
where id = 1;
update Emp set remark = json_object('addr', "๋ถ์ฐ", "age", 38)
where id = 2;
update Emp set remark = json_object('addr', "๋๊ตฌ", "age", 28,
"family", json_array(
json_object('name', '๋
ผ๊ฐ', 'relation', '๋ชจ')
))
where id = 3;
-- {
-- "age": 48,
-- "addr": "๊ฐ์",
-- "family": [
-- {
-- "name": "์กฐ์กฐ",
-- "relation": "๋ถ"
-- },
-- {
-- "name": "๋ฐฐ์ฒ ๊ท ",
-- "relation": "๋ชจ"
-- }
-- ]
-- }
update Emp set remark = json_object('addr', "๊ฐ์", "age", 48,
"family", json_array(
json_object("name", "์กฐ์กฐ", "relation", "๋ถ"),
json_object("name", "๋ฐฐ์ฒ ๊ท ", "relation", "๋ชจ")
))
where id = 4;
JSON ๊ฐ ์ถ์ถ
select remark,
remark->'$.addr', -- $๋ ๋ฃจํธ
remark->>'$.addr', -- >> ๊บฝ์๊ฐ ๋๊ฐ๋ฉด ์๋ฐ์ดํ๊ฐ ์์ด์ง๋ค.
json_value(remark, '$.addr'),
json_value(remark, '$.age' returning decimal(4,2)),
-- remark ๋์ค๊ธฐ ์ ..
json_extract(remark, '$.addr'),
json_unquote(json_extract(remark, '$.addr'))
from Emp
where remark is not null;
+-------------------------------------------------------------------------------------------------------------------+------------------+-------------------+------------------------------+----------------------------------------------------+--------------------------------+----------------------------------------------+
| remark | remark->'$.addr' | remark->>'$.addr' | json_value(remark, '$.addr') | json_value(remark, '$.age' returning decimal(4,2)) | json_extract(remark, '$.addr') | json_unquote(json_extract(remark, '$.addr')) |
+-------------------------------------------------------------------------------------------------------------------+------------------+-------------------+------------------------------+----------------------------------------------------+--------------------------------+----------------------------------------------+
| {"addr": "๋์ "} | "๋์ " | ๋์ | ๋์ | NULL | "๋์ " | ๋์ |
| {"age": 38, "addr": "๋ถ์ฐ"} | "๋ถ์ฐ" | ๋ถ์ฐ | ๋ถ์ฐ | 38.00 | "๋ถ์ฐ" | ๋ถ์ฐ |
| {"age": 28, "addr": "๋๊ตฌ", "family": [{"name": "๋
ผ๊ฐ", "relation": "๋ชจ"}]} | "๋๊ตฌ" | ๋๊ตฌ | ๋๊ตฌ | 28.00 | "๋๊ตฌ" | ๋๊ตฌ |
| {"age": 48, "addr": "๊ฐ์", "family": [{"name": "์กฐ์กฐ", "relation": "๋ถ"}, {"name": "๋ฐฐ์ฒ ๊ท ", "relation": "๋ชจ"}]} | "๊ฐ์" | ๊ฐ์ | ๊ฐ์ | 48.00 | "๊ฐ์" | ๊ฐ์ |
+-------------------------------------------------------------------------------------------------------------------+------------------+-------------------+------------------------------+----------------------------------------------------+--------------------------------+----------------------------------------------+
4 rows in set (0.00 sec)
JSON ๊ฒ์
select remark,
json_search(remark, 'one', '๋ถ์ฐ'), -- ๊ฒฐ๊ณผ๋ก path๋ฅผ ์๋ ค์ค๋ค.
json_search(remark, 'one', '๋ฐฐ์ฒ ๊ท '),
json_value(remark, "$.family[0].name")
from Emp
where remark is not null;
+-------------------------------------------------------------------------------------------------------------------+------------------------------------+--------------------------------------+----------------------------------------+
| remark | json_search(remark, 'one', '๋ถ์ฐ') | json_search(remark, 'one', '๋ฐฐ์ฒ ๊ท ') | json_value(remark, "$.family[0].name") |
+-------------------------------------------------------------------------------------------------------------------+------------------------------------+--------------------------------------+----------------------------------------+
| {"addr": "๋์ "} | NULL | NULL | NULL |
| {"age": 38, "addr": "๋ถ์ฐ"} | "$.addr" | NULL | NULL |
| {"age": 28, "addr": "๋๊ตฌ", "family": [{"name": "๋
ผ๊ฐ", "relation": "๋ชจ"}]} | NULL | NULL | ๋
ผ๊ฐ |
| {"age": 48, "addr": "๊ฐ์", "family": [{"name": "์กฐ์กฐ", "relation": "๋ถ"}, {"name": "๋ฐฐ์ฒ ๊ท ", "relation": "๋ชจ"}]} | NULL | "$.family[1].name" | ์กฐ์กฐ |
+-------------------------------------------------------------------------------------------------------------------+------------------------------------+--------------------------------------+----------------------------------------+
4 rows in set (0.00 sec)
JSON ๊ฒ์ 2
select remark,
json_contains(remark, '"๋ถ์ฐ"', '$.addr'),
json_contains(remark, '48', '$.age')
from Emp
where remark is not null;
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------+--------------------------------------+
| remark | json_contains(remark, '"๋ถ์ฐ"', '$.addr') | json_contains(remark, '48', '$.age') |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------+--------------------------------------+
| {"addr": "๋์ "} | 0 | NULL |
| {"age": 38, "addr": "๋ถ์ฐ"} | 1 | 0 |
| {"age": 28, "addr": "๋๊ตฌ", "family": [{"name": "๋
ผ๊ฐ", "relation": "๋ชจ"}]} | 0 | 0 |
| {"age": 48, "addr": "๊ฐ์", "family": [{"name": "์กฐ์กฐ", "relation": "๋ถ"}, {"name": "๋ฐฐ์ฒ ๊ท ", "relation": "๋ชจ"}]} | 0 | 1 |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------+--------------------------------------+
4 rows in set (0.01 sec)
select * from Emp where json_contains(remark, '48', '$.age');
+----+--------+------+--------+-------------------------------------------------------------------------------------------------------------------+
| id | ename | dept | salary | remark |
+----+--------+------+--------+-------------------------------------------------------------------------------------------------------------------+
| 4 | ์ตํธ์ | 5 | 400 | {"age": 48, "addr": "๊ฐ์", "family": [{"name": "์กฐ์กฐ", "relation": "๋ถ"}, {"name": "๋ฐฐ์ฒ ๊ท ", "relation": "๋ชจ"}]} |
+----+--------+------+--------+-------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
select * from Emp where json_value(remark, '$.age') = 48;
+----+--------+------+--------+-------------------------------------------------------------------------------------------------------------------+
| id | ename | dept | salary | remark |
+----+--------+------+--------+-------------------------------------------------------------------------------------------------------------------+
| 4 | ์ตํธ์ | 5 | 400 | {"age": 48, "addr": "๊ฐ์", "family": [{"name": "์กฐ์กฐ", "relation": "๋ถ"}, {"name": "๋ฐฐ์ฒ ๊ท ", "relation": "๋ชจ"}]} |
+----+--------+------+--------+-------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
select * from Emp where remark->>'$.age' = 48;
+----+--------+------+--------+-------------------------------------------------------------------------------------------------------------------+
| id | ename | dept | salary | remark |
+----+--------+------+--------+-------------------------------------------------------------------------------------------------------------------+
| 4 | ์ตํธ์ | 5 | 400 | {"age": 48, "addr": "๊ฐ์", "family": [{"name": "์กฐ์กฐ", "relation": "๋ถ"}, {"name": "๋ฐฐ์ฒ ๊ท ", "relation": "๋ชจ"}]} |
+----+--------+------+--------+-------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
# rollup
select
(case when d.pid is not null then max(p.dname) else 'Total' end) '์์๋ถ์',
(case when d.id is not null then max(d.dname) else '- ์๊ณ -' end) '๋ถ์๋ช
',
format(sum(e.salary), 0) '๊ธ์ฌํฉ(๋จ์:๋ง์)'
from Dept p inner join Dept d on p.id = d.pid
inner join Emp e on d.id = e.dept
group by d.pid, d.id
with rollup;
+----------+----------+-------------------+
| ์์๋ถ์ | ๋ถ์๋ช
| ๊ธ์ฌํฉ(๋จ์:๋ง์) |
+----------+----------+-------------------+
| ์์
๋ถ | ์์
1ํ | 28,600 |
| ์์
๋ถ | ์์
2ํ | 24,900 |
| ์์
๋ถ | ์์
3ํ | 20,700 |
| ์์
๋ถ | - ์๊ณ - | 74,200 |
| ๊ฐ๋ฐ๋ถ | ์๋ฒํ | 29,600 |
| ๊ฐ๋ฐ๋ถ | ํด๋ผํ | 23,700 |
| ๊ฐ๋ฐ๋ถ | - ์๊ณ - | 53,300 |
| Total | - ์๊ณ - | 127,500 |
+----------+----------+-------------------+
8 rows in set (0.00 sec)
# pivot
select d.id, max(d.dname) '๊ตฌ๋ถ',
format(avg(e.salary) * 10000, 0) 'ํ๊ท ๊ธ์ฌ',
format(sum(e.salary) * 10000, 0) '๊ธ์ฌํฉ๊ณ',
format(min(e.salary) * 10000, 0) '์ต์๊ธ์ฌ',
format(max(e.salary) * 10000, 0) '์ต๋๊ธ์ฌ'
from Dept d inner join Emp e on d.id = e.dept
group by d.id
order by d.id;
+----+---------+-----------+-------------+-----------+-----------+
| id | ๊ตฌ๋ถ | ํ๊ท ๊ธ์ฌ | ๊ธ์ฌํฉ๊ณ | ์ต์๊ธ์ฌ | ์ต๋๊ธ์ฌ |
+----+---------+-----------+-------------+-----------+-----------+
| 3 | ์์
1ํ | 4,612,903 | 286,000,000 | 1,000,000 | 9,000,000 |
| 4 | ์์
2ํ | 5,297,872 | 249,000,000 | 1,000,000 | 9,000,000 |
| 5 | ์์
3ํ | 4,500,000 | 207,000,000 | 1,000,000 | 9,000,000 |
| 6 | ์๋ฒํ | 5,381,818 | 296,000,000 | 1,000,000 | 9,000,000 |
| 7 | ํด๋ผํ | 4,647,059 | 237,000,000 | 1,000,000 | 9,000,000 |
+----+---------+-----------+-------------+-----------+-----------+
5 rows in set (0.00 sec)
select 'ํ๊ท ๊ธ์ฌ' as '๊ตฌ๋ถ',
format(avg(case when dept = 3 then salary end) * 10000, 0) '์์
1ํ',
format(avg(case when dept = 4 then salary end) * 10000, 0) '์์
2ํ',
format(avg(case when dept = 5 then salary end) * 10000, 0) '์์
3ํ',
format(avg(case when dept = 6 then salary end) * 10000, 0) '์๋ฒํ',
format(avg(case when dept = 7 then salary end) * 10000, 0) 'ํด๋ผํ'
from Emp
UNION
select '๊ธ์ฌํฉ๊ณ',
format(sum(salary * (dept = 3)) * 10000, 0), -- ๋ถ์๊ฐ 3์ด๋ฉด 1์ด๋๊น.. ๋ถ์๊ฐ 3์ธ ์ง์์ salary๋ง ๊ฐ์ ธ์จ๋ค
format(sum(salary * (dept = 4)) * 10000, 0),
format(sum(salary * (dept = 5)) * 10000, 0),
format(sum(salary * (dept = 6)) * 10000, 0),
format(sum(salary * (dept = 7)) * 10000, 0)
from Emp
UNION
select '์ต์๊ธ์ฌ',
format(min(IF(dept = 3, salary, ~0)) * 10000, 0), -- ~0: integer์ ์ต๋๊ฐ
format(min(IF(dept = 4, salary, ~0)) * 10000, 0),
format(min(IF(dept = 5, salary, ~0)) * 10000, 0),
format(min(IF(dept = 6, salary, ~0)) * 10000, 0),
format(min(IF(dept = 7, salary, ~0)) * 10000, 0)
from Emp
UNION
select '์ต๋๊ธ์ฌ',
format(max(IF(dept = 3, salary, 0)) * 10000, 0),
format(max(IF(dept = 4, salary, 0)) * 10000, 0),
format(max(IF(dept = 5, salary, 0)) * 10000, 0),
format(max(IF(dept = 6, salary, 0)) * 10000, 0),
format(max(IF(dept = 7, salary, 0)) * 10000, 0)
from Emp
;
+----------+-------------+-------------+-------------+-------------+-------------+
| ๊ตฌ๋ถ | ์์
1ํ | ์์
2ํ | ์์
3ํ | ์๋ฒํ | ํด๋ผํ |
+----------+-------------+-------------+-------------+-------------+-------------+
| ํ๊ท ๊ธ์ฌ | 4,612,903 | 5,297,872 | 4,500,000 | 5,381,818 | 4,647,059 |
| ๊ธ์ฌํฉ๊ณ | 286,000,000 | 249,000,000 | 207,000,000 | 296,000,000 | 237,000,000 |
| ์ต์๊ธ์ฌ | 1,000,000 | 1,000,000 | 1,000,000 | 1,000,000 | 1,000,000 |
| ์ต๋๊ธ์ฌ | 9,000,000 | 9,000,000 | 9,000,000 | 9,000,000 | 9,000,000 |
+----------+-------------+-------------+-------------+-------------+-------------+
4 rows in set (0.00 sec)
# Reference
inflearn_@์์ฝ - MySQL ์ ๋๋ก ๋ฐฐ์ฐ๊ธฐ (opens new window)
๊ฐ์ github (opens new window)
๊ฐ์ slide (opens new window)
mysql ์ฌ์ฉ์ (opens new window)