본문 바로가기

MySQL/MySQL Tip & Tech

[MySQL] VALUES - keyword, function & statement

Keyword 로서의 VALUES

  • INSERT 문에서 삽입할 값을 나열할 때 VALUES 를 사용합니다. 이 때의 VALUES는 keyword 입니다.
    
    INSERT INTO table_name (col1, col2, col3)
    VALUES ('value1', 'value2', 'value3');

Function 으로서의 VALUES()

  • 일반적인 INSERT … ON DUPLICATE KEY UPDATE 문은 아래와 같습니다.
    
    INSERT INTO table_name (id, col1, col2)
    VALUES ('key_value', 'value1', 'value2') -- VALUE keyword
    ON DUPLICATE KEY UPDATE
    	  col1 = 'value1'
    	, col2 = 'value2';
  • 여기 'values1', 'values2'를 직접 작성하는 대신 아래와 같이 VALUES() 함수를 사용하는 것이 코딩의 간결함이나 가독성 면에서 더 낫습니다.
    
    INSERT INTO table_name (id, col1, col2)
    VALUES ('key_value', 'value1', 'value2') -- VALUE keyword
    ON DUPLICATE KEY UPDATE
    	  col1 = VALUES(col1)  -- VALUES() function
    	, col2 = VALUES(col2); -- VALUES() function

Statement 로서의 VALUES

  • DML 문 (statement)에 무엇이 있나요?
    • INSERT statement
    • SELECT statement
    • UPDATE statement
    • DELETE statement
  • MySQL 8.0.19 이후 사용할 수 있게 된 새로운 DML statement가 바로 VALUES statement 입니다.
    • VALUES 문은 테이블을 참조하지 않은 상태에서, SELECT 문처럼 하나 또는 여러 행을 리턴해 주는 구문입니다.
    • 테이블 없이 값을 Result Set으로 반환할 수 있기 때문에 “테이블 값 생성자” (table value constructor) 라고도 부릅니다.
    • 아래 예문에서 ROW 는 “행 값 생성자” (row value constructor) 입니다.
      
      VALUES ROW(1, 'banana', 'y') -- VALUES statement
      	, ROW(2, 'apple', 'n');
      
      /*
      (result)
      +----------+----------+----------+
      | column_0 | column_1 | column_2 |
      +----------+----------+----------+
      |        1 |   banana |        y |
      |        2 |    apple |        n |
      +----------+----------+----------+
      */
  • 이전에  VALUES 문이 없었을 때는 아래와 같이 SELECT 문을 UNION ALL로 결합 시켜야 했습니다.
    
    SELECT 1 AS column_0, 'banana' AS column_1, 'y' AS column_2
    UNION ALL
    SELECT 2, 'apple', 'n';
    
    /*
    (result)
    +----------+----------+----------+
    | column_0 | column_1 | column_2 |
    +----------+----------+----------+
    |        1 |   banana |        y |
    |        2 |    apple |        n |
    +----------+----------+----------+
    */
  • VALUES 문은 어디에 사용할까요?
    저는 테이블 없이 임의의 값을 코드로 만들어내야 할 때 CTE와 결합하여 사용하곤 합니다.
    
    WITH c (kind) AS (
    	VALUES ROW(1), ROW(2)
    )
    SELECT c.kind, t.*
    FROM table_name t
    	CROSS JOIN c; -- t 테이블의 행을 두 번씩 출력
     

생각해 보기

  • 다음 구문의 VALUES 는 keyword일까요? 아니면 statement일까요?
    
    INSERT INTO table_name (col1, col2, col3)
    VALUES ('value1', 'value2', 'value3')
    	, ('values4', 'values5', 'values6');


  • VALUES 이하가 독립적으로 실행할 수 없는 구문이기 때문에 statement 가 아닙니다. 이 경우 VALUES는 keyword 입니다. VALUES 문으로 고쳐 쓰면 아래와 같습니다.
    
    INSERT INTO table_name (col1, col2, col3)
    VALUES ROW('value1', 'value2', 'value3')
    	, ROW('values4', 'values5', 'values6'); -- VALUES statement


  • 하지만, 관례 상 선호 되는 구문은 첫 번째입니다.
    굳이 VALUES statement를 사용해서 구문을 복잡하게 만들 이유가 없기 때문입니다.

    Simple is the Best