Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DuckDB雑紹介

Ktz
June 23, 2024

 DuckDB雑紹介

DuckDBを触っていて特に興味を持った機能を中心に雑解説します。

Ktz

June 23, 2024
Tweet

More Decks by Ktz

Other Decks in Technology

Transcript

  1. 構文 データ型 だいたい PostgreSQL と同じ Enum や PostgreSQL 式の型キャスト( ::

    )も使える https://duckdb.org/docs/sql/data_types/overview 11/57
  2. 構文 CTEの式内materialization たぶん PostgreSQL 独自機能 materialize の強制 or 解除 WITH

    v AS NOT MATERIALIZE (...) SELECT * v https://www.postgresql.jp/document/16/html/queries- with.html#QUERIES-WITH-CTE-MATERIALIZATION 12/57
  3. 構文 LATERAL JOIN 公式だと直積での説明しかなくて残念 相関サブクエリの JOIN もちゃんとできるので安心 SELECT * FROM

    t1 JOIN LATERAL (...) t2 ON true https://duckdb.org/docs/sql/query_syntax/from#lateral-joins ちなみに LATERAL は飾りでしかなく、相関サブクエリの JOIN はなく てもできる 14/57
  4. 構文 Window関数 もちのろん、Windowフレームも使える ただし、 Row と Range のみ Group は使えない

    (使えるの PostgreSQL くらいだけど・・・) https://duckdb.org/docs/sql/window_functions#framing 特にWindowフレームの説明がわかりやすいので一見の価値あり 15/57
  5. SELECT文の独自機能 - JOIN拡張 ASOF JOIN 用途としては、指定日以前・以後の直近のログデータをもってくる とか SELECT t1.some_date, ...

    FROM t1 ASOF JOIN t2 ON t1 t1.some_date > t2.some_date https://duckdb.org/docs/sql/query_syntax/from#as-of-joins 20/57
  6. SELECT文の独自機能 - JOIN拡張 ASOF JOIN 標準SQLで書くとスッゲーめんどいやつ SELECT t1.some_date, ... WHERE

    t1.some_date = ( SELECT max(t2.some_date) FROM t2 WHERE t2.some_date < t1.some_date ) 21/57
  7. SELECT文の独自機能 - JOIN拡張 POSITIONAL JOIN 2つのデータソースの同一行で結合する 欠損行は NULL に 実体は

    FULL OUTER JOIN なので zip演算を思い浮かべるとわかりやすいかも SELECT * FROM t1 POSITIONAL JOIN t2 https://duckdb.org/docs/sql/query_syntax/from#positional-joins 22/57
  8. SELECT文の独自機能 - 集約関数 ソート可能な集約関数 CREATE TABLE tbl AS SELECT s

    FROM range(1, 4) r(s); SELECT string_agg(s, ', ' ORDER BY s DESC) AS countdown FROM tbl PostgreSQLの「順序集合集約関数」に似てるけど別物っぽい DuckDBも「順序集合集約関数」をサポートしているわけで https://duckdb.org/docs/sql/aggregates#order-by-clause-in- aggregate-functions 23/57
  9. SELECT文の独自機能 - 集約関数 配列・リスト型用の関数でラムダ式が使える さらにメソッドチェインもできる SELECT [1, 2, 3].apply(x ->

    [4, 5, 6].reduce((a, b) -> a + b) + x) https://duckdb.org/docs/sql/functions/lambda ただしメソッドチェインは、配列・リスト型用の関数のみ TOUPPER とか他の関数はできなかった。残念! 24/57
  10. SELECT文の独自機能 - スター拡張 COLUMNS(*) * の指定で、全ての列にまとめて同じ関数を適用できる CREATE TABLE numbers (id

    INTEGER, number INTEGER); INSERT INTO numbers VALUES (1, 10), (2, 20), (3, NULL); /* 4列帰ってくる */ SELECT min(COLUMNS(*)), count(COLUMNS(*)) FROM numbers; https://duckdb.org/docs/sql/expressions/star#columns-expression 26/57
  11. SELECT文の独自機能 - スター拡張 COLUMNS(<パターン>) 正規表現による列名のパターンマッチ ラムダ式も使える CREATE TABLE t (yobi001

    VARCHAR, ..., yobi256 VARCHAR); SELECT COLUMNS( c -> substr(c, 5)::int BETWEEN 10 AND 20) FROM t; https://duckdb.org/docs/sql/expressions/star#columns-expression 27/57
  12. SELECT文の独自機能 - スター拡張 REPLACE(<式 AS 列名>) 特定列だけ変更できる INSERT-SELECT で大活躍の予感 INSERT

    INTO t2 SELECT * REPLACE(id*100 AS id) FROM t1 https://duckdb.org/docs/sql/expressions/star 29/57
  13. SELECT文の独自機能 - from first syntax FROM句から先に書ける。ただし・・・ FROM + SELECT or

    FROM + WHERE のみ もしくは FROM のみで全列選択 FROM WHERE SELECT は書けない残念な子 /* FROMのみ (SELECT * FROM foo と同等) */ FROM foo; /* FROM WHEREの例 */ SELECT EXISTS (FROM foo WHERE id > 5); https://duckdb.org/docs/sql/query_syntax/from#from-first-syntax 34/57
  14. SELECT文の独自機能 - GROUP BY GROUP BY ALL 集約関数を適用した列以外でグループ化 SELECT a,

    b, max(c), count(c) FROM t GROUP BY ALL https://duckdb.org/docs/sql/query_syntax/groupby#group-by-all 35/57
  15. SELECT文の独自機能 - ORDER BY ORDER BY ALL SELECT句のすべてのカラム一括指定 ASC /

    DESCが揃ってる場合は便利かも SELECT A1, A2, A3 FROM t ORDER BY ALL https://duckdb.org/docs/sql/query_syntax/orderby#order-by-all 36/57
  16. INSERT文の独自機能 - Upsert INSERT OR REPLACE SQLiteで提供されてるやつ なかったら INSERT あったら

    UPDATE PostgreSQLの ON CONFLICT DO も使えるがより直感的 INSERT OR REPLACE INTO movies VALUES (1, 'The Phantom Menace'); https://duckdb.org/2023/02/13/announcing-duckdb-070.html#new- sql-features 40/57
  17. INSERT文の独自機能 - BY NAME INSERT SELECT で、いちいち位置を合わせなくても列名でマッチ ングしてくれる CREATE TABLE

    tbl (a INTEGER, b INTEGER); INSERT INTO tbl BY NAME (SELECT 42 AS b, 32 AS a); https://duckdb.org/docs/sql/statements/insert#insert-into--by-name 41/57
  18. 独自STATEMENT - PIVOT / UNPIVOT 行と列の転置 文として提供されている 大抵のRDBは関数として提供 PIVOT Cities

    ON Year USING sum(Population); PIVOT: https://duckdb.org/docs/sql/statements/pivot UNPIVOT: https://duckdb.org/docs/sql/statements/unpivot 45/57
  19. できなかったこと ネストした Derived Table で複数回、 unnest するとデータが欠損 先頭行のみもってくる SELECT *

    FROM ( SELECT unnest(bar) FROM ( SELECT unnest(foo) FROM t ) ) 遭遇したのはデータソースとして JSON を使った時 テンポラリテーブルで、分けて対処した 51/57
  20. できなかったこと - JS/TSバインディング SQL実行APIで、 Array や Object をパラメータとして使えない 渡せるのは、 数値

    、 文字列 、 boolean 、 NULL のみ 上記以外は、 「Invalid column type encountered for argument」 ってエラーになる IN句 や ANY句 に渡す場合は展開する必要あり CLI ではできるのでバインディングの制限か? 53/57
  21. おわり あばうとみー X(旧トゥイッタ) - https://x.com/ktz_alias Qiita - https://qiita.com/ktz_alias Zenn -

    https://zenn.dev/ktz_alias ギッハブ - https://github.com/ritalin 57/57