Friendly SQL

Friendly SQL

DuckDB는 SQL 쿼리를 더 간결하게 만들어주는 여러 고급 SQL 기능과 문법적 설탕(syntactic sugar)을 제공해요. 이를 흔히 "friendly SQL"이라고 부른답니다. SQL을 더 짧고 읽기 좋게 쓰고 싶다면 이 기능들을 눈여겨볼 만해요.

출처: 문서

본문

DuckDB는 SQL 쿼리를 더 간결하게 만들어주는 여러 고급 SQL 기능과 문법적 설탕을 제공해요. 우리는 이를 비공식적으로 "friendly SQL"이라고 불러요.

이 기능 중 몇몇은 DuckDB가 처음 도입했고, 일부는 다른 시스템에서 영감을 받았어요. DuckDB가 처음 도입한 많은 기능(예: GROUP BY ALL)은 이후 다른 시스템들도 채택했어요.

팁 (Tip) 12개의 friendly SQL 기능에 대한 짧은 설명, 예시, 요약 일러스트가 담긴 Friendly SQL 2026 캘린더가 있어요.

절 (Clauses)

  • 테이블 생성 및 데이터 삽입:
    • CREATE OR REPLACE TABLE: 스크립트에서 DROP TABLE IF EXISTS 문을 피할 수 있어요.
    • CREATE TABLE ... AS SELECT (CTAS): 스키마를 수동으로 정의하지 않고 테이블의 출력으로 새 테이블을 만들어요.
    • INSERT INTO ... BY NAME: INSERT 문의 이 변형은 위치 대신 컬럼 이름을 사용할 수 있게 해줘요.
    • INSERT OR IGNORE INTO ...: UNIQUEPRIMARY KEY 제약으로 인한 충돌이 없는 행을 삽입해요.
    • INSERT OR REPLACE INTO ...: UNIQUEPRIMARY KEY 제약으로 인한 충돌이 없는 행을 삽입하고, 충돌하는 행은 기존 행의 컬럼을 삽입될 새 행의 값으로 교체해요.
  • 테이블 설명 및 통계 계산:
    • DESCRIBE: 테이블이나 쿼리의 스키마를 간결하게 요약해줘요.
    • SUMMARIZE: 테이블이나 쿼리에 대한 요약 통계를 반환해요.
  • SQL 절을 더 압축하고 읽기 좋게 만들기:
  • 테이블 변환:
    • 장(long) 테이블을 넓은(wide) 테이블로 바꾸는 PIVOT.
    • 넓은 테이블을 장 테이블로 바꾸는 UNPIVOT.
  • SQL 수준 변수 정의:

쿼리 기능 (Query Features)

리터럴과 식별자 (Literals and Identifiers)

데이터 타입 (Data Types)

데이터 가져오기 (Data Import)

함수와 표현식 (Functions and Expressions)

조인 타입 (Join Types)

트레일링 콤마 (Trailing Commas)

DuckDB는 트레일링 콤마를 허용해요. 엔티티 목록(예: 컬럼·테이블 이름)을 나열할 때나 LIST 항목을 구성할 때 모두요. 예를 들어 다음 쿼리는 작동해요:

SELECT
    42 AS x,
    ['a', 'b', 'c',] AS y,
    'hello world' AS z,
;

"그룹 내 Top-N" 쿼리 ("Top-N in Group" Queries)

일부 기준에 따라 정렬된 "그룹 내 top-N 행"을 계산하는 것은 SQL에서 흔한 작업인데, 불행히도 종종 윈도우 함수나 서브쿼리를 포함한 복잡한 쿼리가 필요해요.

이를 돕기 위해 DuckDB는 집계 함수 max(arg, n), min(arg, n), arg_max(arg, val, n), arg_min(arg, val, n), max_by(arg, val, n), min_by(arg, val, n)을 제공해서 특정 컬럼을 기준으로 오름차순 또는 내림차순으로 그룹의 "top" n 행을 효율적으로 반환해요.

예를 들어 다음 테이블을 사용해 보세요:

SELECT * FROM t1;
┌─────────┬───────┐
│   grp   │  val  │
│ varchar │ int32 │
├─────────┼───────┤
│ a       │     2 │
│ a       │     1 │
│ b       │     5 │
│ b       │     4 │
│ a       │     3 │
│ b       │     6 │
└─────────┴───────┘

각 그룹 grp에서 top-3 val 값의 목록을 얻고 싶다고 해요. 전통적인 방법은 서브쿼리에서 윈도우 함수를 사용하는 거예요:

SELECT array_agg(rs.val), rs.grp
FROM
    (SELECT val, grp, row_number() OVER (PARTITION BY grp ORDER BY val DESC) AS rid
    FROM t1 ORDER BY val DESC) AS rs
WHERE rid < 4
GROUP BY rs.grp;
┌───────────────────┬─────────┐
│ array_agg(rs.val) │   grp   │
│      int32[]      │ varchar │
├───────────────────┼─────────┤
│ [3, 2, 1]         │ a       │
│ [6, 5, 4]         │ b       │
└───────────────────┴─────────┘

하지만 DuckDB에서는 이걸 훨씬 더 간결하게(그리고 효율적으로!) 할 수 있어요:

SELECT max(val, 3) FROM t1 GROUP BY grp;
┌─────────────┐
│ max(val, 3) │
│   int32[]   │
├─────────────┤
│ [3, 2, 1]   │
│ [6, 5, 4]   │
└─────────────┘

더 알아보기 (Learn more)