14. การนำเข้าและส่งออกข้อมูลด้วย DuckDB

บทนำ

DuckDB มีจุดแข็งด้านการ อ่านและเขียนไฟล์ข้อมูลหลายรูปแบบโดยตรงจาก SQL โดยไม่ต้องพึ่งเครื่องมือภายนอก ไม่ว่าจะเป็น CSV, Excel, หรือ Parquet ความสามารถนี้ทำให้ DuckDB เหมาะอย่างยิ่งสำหรับงานวิเคราะห์ข้อมูลที่ต้องเชื่อมต่อกับไฟล์จากหลายแหล่งและทำงานได้อย่างคล่องตัวภายในสภาพแวดล้อมเดียว

บทนี้จะแนะนำวิธีทำงานกับรูปแบบไฟล์ที่พบได้บ่อยในงานจริง พร้อมยกตัวอย่างจากฐานข้อมูล PiCha Tea House เพื่อให้ผู้เรียนสามารถนำ DuckDB ไปใช้ร่วมกับเครื่องมือและชุดข้อมูลที่มีอยู่ได้อย่างสะดวกและมีประสิทธิภาพ

ทำงานกับไฟล์ CSV

CSV (Comma-Separated Values) เป็นไฟล์ข้อความที่เก็บข้อมูลในรูปแบบตาราง แต่ละแถวคือหนึ่งระเบียน และแต่ละคอลัมน์ คั่นด้วยเครื่องหมายคอมมา (หรืออักขระตัวคั่นอื่นเช่น ; หรือ |) ระบบส่วนใหญ่รองรับ CSV จึงเป็นมาตรฐานการแลกเปลี่ยนข้อมูลที่นิยมที่สุดในงานจริง

DuckDB อ่านไฟล์ CSV ได้โดยตรงผ่านชื่อไฟล์หรือฟังก์ชัน read_csv() ซึ่งสามารถตรวจจับ schema อัตโนมัติ และรองรับ option สำหรับกรณีไฟล์มีรูปแบบพิเศษ เช่น ตัวคั่นที่ไม่ใช่คอมมา encoding ที่ต่างออกไป หรือค่าที่ใช้แทน NULL

การอ่าน CSV

DuckDB รองรับการอ่านไฟล์ CSV โดยตรงด้วย SELECT โดยไม่ต้องใช้ฟังก์ชัน read_csv() ให้ยุ่งยาก

วิธีที่ 1 อ่านตรงจากชื่อไฟล์ (แบบสั้นที่สุด)

SELECT * FROM 'stores.csv';

อ่านแบบระบุตำแหน่งที่ตั้งของไฟล์ (File Path)

SELECT * FROM './data/stores.csv';

เส้นทางไฟล์ './data/stores.csv' ใช้สัญลักษณ์ . แทน โฟลเดอร์ปัจจุบัน (Current Working Directory) ซึ่งคือโฟลเดอร์ที่เปิด DuckDB หรือรันสคริปต์อยู่

รูปแบบ Path ตัวอย่าง ความหมาย
Current folder 'stores.csv' ไฟล์อยู่ในโฟลเดอร์ตอนรัน DuckDB
Relative './data/stores.csv' นับจากโฟลเดอร์ที่รันสคริปต์
Absolute (Linux, macOS) '/home/user/project/data/stores.csv' ระบุตำแหน่งเต็มจาก root
Absolute (Windows) 'c:\temp\stores.csv' หรือ 'c:/temp/stores.csv' ระบุตำแหน่งเต็มจาก root ในไดรฟ์ C (ใชได้ทั้ง / และ \ ในการแบ่ง file path)

ข้อดีของ Relative Path คือย้ายโฟลเดอร์โปรเจกต์ไปที่ไหนก็ยังใช้งานได้ ต่างจาก Absolute Path ที่ต้องแก้ไขทุกครั้งที่เปลี่ยนเครื่องหรือเปลี่ยน User

วิธีที่ 2 อ่านจาก URL โดยตรง

SELECT * FROM 'https://github.com/prasertcbs/picha/raw/refs/heads/main/csv/stores.csv';

วิธีที่ 3 ใช้ฟังก์ชัน read_csv() (ควบคุมได้มากกว่า)

SELECT *          -- ดึงข้อมูลทุกคอลัมน์
FROM read_csv(
 'stores.csv',    -- ชื่อไฟล์ CSV ที่ต้องการอ่าน
 header = true,   -- บรรทัดแรกของไฟล์เป็นชื่อคอลัมน์
 delim = ','      -- ใช้เครื่องหมายจุลภาค (,) เป็นตัวคั่นข้อมูล
);

วิธีที่ 4 สร้างตารางจาก CSV

-- สร้างตาราง stores โดยนำเข้าข้อมูลจากไฟล์ CSV โดยตรง
CREATE TABLE stores AS
SELECT * FROM read_csv(
 'stores.csv',   -- ไฟล์ CSV ที่ต้องการนำเข้า
 header = true   -- แถวแรกเป็น header (ชื่อ column)
);

วิธีที่ 5 ใช้ COPY เมื่อมี schema ตายตัวล่วงหน้า

-- สร้างตาราง stores และนำเข้าข้อมูลจากไฟล์ CSV

CREATE TABLE stores (
 store_id    INTEGER, -- รหัสสาขา
 store_name  VARCHAR, -- ชื่อสาขา
 branch_type VARCHAR, -- ประเภทสาขา (เช่น mall, office)
 district    VARCHAR  -- ย่านที่ตั้งสาขา
);

COPY stores FROM 'stores.csv' (HEADER true); -- นำเข้าข้อมูลจาก CSV โดยใช้แถวแรกเป็น header

Parameters ที่ใช้บ่อย

Parameter ความหมาย ค่าเริ่มต้น ตัวอย่าง
header แถวแรกคือชื่อคอลัมน์ false header = true
delim ตัวคั่น field , delim = '|'
encoding encoding ของไฟล์ utf-8 encoding = 'latin-1'
skip ข้ามกี่แถวแรก 0 skip = 2
null ค่าที่แทน NULL '' null = 'N/A'
compression การบีบอัด auto compression = 'gzip'
all_varchar อ่านทุกคอลัมน์เป็น text false all_varchar = true

ตัวอย่างใช้หลาย parameter พร้อมกัน:

-- อ่านไฟล์ CSV ที่บีบอัดด้วย gzip และใช้ | เป็นตัวคั่น

SELECT * FROM read_csv(
    'transactions_export.csv', -- ชื่อไฟล์ CSV ที่ต้องการอ่าน
    header      = true,        -- แถวแรกเป็น header (ชื่อ column)
    delim       = '|',         -- ใช้ | เป็นตัวคั่น column
    encoding    = 'utf-8',     -- อ่านไฟล์ด้วย encoding UTF-8
    null        = 'NULL',      -- แปลงค่า 'NULL' ในไฟล์เป็น NULL
    compression = 'gzip'       -- ไฟล์ถูกบีบอัดด้วย gzip
);

การเขียน CSV

คำสั่ง COPY ... TO ส่งออกข้อมูลจาก DuckDB ไปยังไฟล์ CSV โดยมีรูปแบบการใช้งาน 2 แบบ

แบบที่ 1 ส่งออกทั้งตาราง ระบุชื่อตารางโดยตรง เหมาะเมื่อต้องการข้อมูลทุกแถวทุกคอลัมน์ เช่น ต้องการส่งออกตาราง transactions ไปเป็นไฟล์ transactions_export.csv

-- ส่งออกทั้งตาราง
COPY transactions TO 'transactions_export.csv' (HEADER true);

แบบที่ 2 ส่งออกจาก Query ใส่คำสั่ง SELECT ไว้ในวงเล็บ ทำให้กรองข้อมูล เลือกคอลัมน์ หรือ JOIN ตารางก่อนส่งออกได้ในขั้นตอนเดียว

-- ส่งออกเฉพาะบางคอลัมน์จาก query
COPY (
    SELECT store_id, order_date, net_sales_thb
    FROM transactions
    WHERE order_date >= '2026-03-01'
) TO 'march_sales.csv' (HEADER true, DELIMITER ',');

ตัวเลือกที่ใช้บ่อยในวงเล็บท้ายคำสั่ง

ตัวเลือก ค่าตัวอย่าง ความหมาย
HEADER true / false ให้บรรทัดแรกแสดงเป็นชื่อคอลัมน์หรือไม่
DELIMITER ',' / '\t' ตัวคั่นข้อมูล (ค่าเริ่มต้นคือจุลภาค)
QUOTE '"' อักขระครอบค่าที่มีตัวคั่นอยู่ภายใน
NULL '' แทนค่า NULL ด้วยข้อความที่กำหนด

ทำงานกับไฟล์ Excel

สำหรับผู้ที่ใช้ Excel เป็นหลัก DuckDB สามารถอ่านและเขียนไฟล์ .xlsx ได้ผ่าน excel extension การใช้งานพื้นฐานเหมือนกับ CSV แต่เพิ่มความสามารถเรื่อง sheet และช่วง cell รวมถึงส่งออกรายงานในรูปแบบที่ผู้ใช้ทั่วไปเปิดอ่านได้ทันที

DuckDB ต้องติดตั้ง extension นี้ครั้งแรกด้วย INSTALL excel; และโหลดทุกครั้งเมื่อเริ่ม session ใหม่ด้วย LOAD excel;

ติดตั้ง Excel Extension

ก่อนการ import/export ข้อมูล ต้องทำการติดตั้งส่วนขยาย extension พร้อมโหลด extension เข้า session ปัจจุบัน (ทำทุกครั้งที่เปิด session ใหม่)

ทำโดยรันโปรแกรม duckdb จากนั้นพิมพ์คำสั่งดังนี้

INSTALL excel; -- ติดตั้ง excel extension (ทำครั้งเดียว)
LOAD excel;    -- โหลด extension เข้า session ปัจจุบัน (ทำทุกครั้งที่เปิด session ใหม่)

การอ่าน Excel

วิธีที่ 1 อ่านจากชื่อไฟล์

SELECT * FROM 'stores.xlsx';

วิธีที่ 2 อ่านจาก URL โดยตรง

SELECT * FROM 'https://github.com/prasertcbs/picha/raw/refs/heads/main/xlsx/stores.xlsx';

วิธีที่ 3 ใช้ฟังก์ชัน read_xlsx() พร้อมกำหนดค่าให้พารามิเตอร์

-- อ่านข้อมูลจากไฟล์ Excel sheet ที่กำหนด
SELECT * FROM read_xlsx(
    'stores.xlsx',  -- ชื่อไฟล์ Excel ที่ต้องการอ่าน
    header = true,  -- แถวแรกเป็น header (ชื่อ column)
    sheet  = 'Sheet1' -- ชื่อ sheet ที่ต้องการอ่าน
);

วิธีที่ 4 ระบุ range ที่ต้องการ เช่น ต้องการอ่านข้อมูลเฉพาะที่อยู่ใน A1:E100 จากชีท Revenue ในไฟล์ report.xlsx

-- อ่านข้อมูลจากช่วงเซลล์ที่กำหนดใน Excel
SELECT * FROM read_xlsx(
    'report.xlsx',    -- ชื่อไฟล์ Excel ที่ต้องการอ่าน
    header = true,    -- แถวแรกเป็น header (ชื่อ column)
    sheet  = 'Revenue', -- ชื่อ sheet ที่ต้องการอ่าน
    range  = 'A1:E100'  -- อ่านเฉพาะช่วงเซลล์ A1 ถึง E100
);

Parameters ของ read_xlsx()

Parameter ความหมาย ค่าเริ่มต้น
header แถวแรกคือชื่อคอลัมน์ false
sheet ชื่อ sheet ที่ต้องการอ่าน sheet แรก
range cell range เช่น A1:E50 ทั้งหมด
all_varchar อ่านทุก cell เป็น text false
ignore_errors แทน cell ที่อ่านไม่ได้ด้วย NULL false
stop_at_empty หยุดอ่านเมื่อเจอแถวว่าง false

การส่งออกเป็นไฟล์ Excel

มีรูปแบบการทำงานเหมือนกับการทำงานกับ CSV ต่างกันเพียงพารามิเตอร์ที่ใช้ในการระบุรายละเอียดบางอย่าง

-- ส่งออกตารางเป็น Excel
COPY stores TO 'stores_export.xlsx' (FORMAT xlsx, HEADER true);

-- ส่งออก query result พร้อมระบุชื่อ sheet
COPY (
 SELECT
     s.store_name,                        -- ชื่อสาขา
     s.branch_type,                       -- ประเภทสาขา
     COUNT(*) AS order_count,             -- จำนวนออร์เดอร์ทั้งหมด
     ROUND(SUM(t.net_sales_thb), 0) AS total_revenue -- รายได้รวม (บาท)
 FROM transactions t
 JOIN stores s ON t.store_id = s.store_id -- เชื่อมตารางสาขาเพื่อดึงชื่อสาขา
 GROUP BY s.store_name, s.branch_type     -- จัดกลุ่มตามสาขาและประเภท
 ORDER BY total_revenue DESC              -- เรียงจากรายได้สูงสุดไปต่ำสุด
) TO 'revenue_report.xlsx' (
    FORMAT xlsx,                  -- บันทึกในรูปแบบ Excel
    HEADER true,                  -- เพิ่มแถว header ในไฟล์
    SHEET 'Revenue by Store'      -- ชื่อ sheet ในไฟล์ Excel
);

ทำงานกับไฟล์ Parquet

Parquet เป็น binary format ที่ออกแบบมาสำหรับงาน analytics โดยเฉพาะ ต่างจาก CSV ที่เก็บข้อมูลแบบ row-by-row เพราะ Parquet เก็บแบบ columnar ทำให้เวลา query ดึงเฉพาะบางคอลัมน์ ระบบอ่านเฉพาะส่วนที่จำเป็น ส่งผลให้เร็วกว่า CSV อย่างชัดเจนในชุดข้อมูลใหญ่ นอกจากนี้ Parquet ยังบีบอัดข้อมูลได้ดีกว่า CSV เพราะข้อมูลในแต่ละ column มักมีรูปแบบซ้ำกัน ทำให้ compression algorithm ทำงานได้อย่างมีประสิทธิภาพ

DuckDB อ่านและเขียนไฟล์ Parquet ได้โดยตรงผ่านฟังก์ชัน read_parquet() และคำสั่ง COPY ... TO

การอ่าน Parquet

วิธีที่ 1 อ่านตรงจากชื่อไฟล์

SELECT * FROM 'transactions.parquet';

วิธีที่ 2 อ่านจาก URL โดยตรง

SELECT * FROM read_parquet('https://github.com/prasertcbs/picha/raw/refs/heads/main/parquet/stores.parquet');

วิธีที่ 3 ใช้ฟังก์ชัน read_parquet()

SELECT * FROM read_parquet('transactions.parquet');

วิธีที่ 4 อ่านหลายไฟล์พร้อมกันด้วย glob pattern

-- อ่านทุก .parquet ในโฟลเดอร์
SELECT * FROM 'data/*.parquet';

-- อ่านหลายโฟลเดอร์
SELECT * FROM read_parquet([
    'data/2026-02/*.parquet', -- อ่านทุกไฟล์ Parquet ในโฟลเดอร์เดือนกุมภาพันธ์
    'data/2026-03/*.parquet'  -- อ่านทุกไฟล์ Parquet ในโฟลเดอร์เดือนมีนาคม
]);

การส่งออกเป็นไฟล์ Parquet

-- ส่งออกตาราง transactions ทั้งหมดเป็นไฟล์ Parquet
COPY transactions TO 'transactions.parquet' (FORMAT parquet);

-- ส่งออกพร้อมระบุ compression algorithm
COPY transactions TO 'transactions.parquet' (
    FORMAT      parquet, -- บันทึกในรูปแบบ Parquet
    COMPRESSION zstd     -- บีบอัดด้วย zstd (ขนาดเล็ก ความเร็วสมดุล)
);

-- ส่งออกเฉพาะ column ที่จำเป็น เพื่อลดขนาดไฟล์
COPY (
    SELECT transaction_id, order_date, net_sales_thb, store_id -- เลือกเฉพาะ 4 column
    FROM transactions
) TO 'transactions_slim.parquet' (
    FORMAT      parquet,  -- บันทึกในรูปแบบ Parquet
    COMPRESSION snappy    -- บีบอัดด้วย snappy (เร็วกว่า zstd แต่ขนาดใหญ่กว่าเล็กน้อย)
);

Compression Options

Algorithm ความเร็ว ขนาดไฟล์ เหมาะกับ
snappy (default) เร็ว ปานกลาง งานทั่วไป
zstd ปานกลาง เล็กมาก เก็บ archive ระยะยาว
lz4 เร็วมาก ปานกลาง อ่าน/เขียนบ่อย
uncompressed เร็วสุด ใหญ่สุด debug / ทดสอบ

ดู Metadata ของไฟล์ Parquet

-- ดู schema
SELECT * FROM parquet_schema('transactions.parquet');

-- ดู metadata ระดับไฟล์
SELECT * FROM parquet_file_metadata('transactions.parquet');

-- ดู metadata ระดับ row group
SELECT * FROM parquet_metadata('transactions.parquet');

อ่านหลายไฟล์พร้อมกัน (ทุกฟอร์แมต)

ในงานจริงเรามักเก็บข้อมูลแยกเป็นหลายไฟล์ เช่น รายเดือนหรือรายวัน DuckDB รองรับ glob pattern เพื่ออ่านหลายไฟล์เป็น dataset เดียวได้ในหลายรูปแบบไฟล์ เช่น CSV และ Parquet

-- อ่าน CSV ทุกไฟล์ในโฟลเดอร์
SELECT * FROM 'monthly_data/*.csv';

-- อ่านหลายโฟลเดอร์สำหรับ CSV
SELECT * FROM read_csv(['data/2026-02/*.csv', 'data/2026-03/*.csv']);

-- รู้ว่าข้อมูลมาจากไฟล์ไหน
SELECT filename, * FROM 'monthly_data/*.csv';

-- รวม Parquet หลายไฟล์ที่ schema ต่างกันด้วย union_by_name
SELECT * FROM read_parquet('data/*.parquet', union_by_name = true);

EXPORT/IMPORT DATABASE สำรองทั้งฐานข้อมูล

จากที่เรา export/import ระดับตารางหรือไฟล์เดี่ยวกันมาแล้ว DuckDB ยังมีคำสั่งสำหรับ backup หรือย้ายฐานข้อมูล ทั้งฐาน ผ่าน EXPORT DATABASE และ IMPORT DATABASE

Export ทั้งฐานข้อมูล

-- Export เป็น CSV (default)
EXPORT DATABASE 'backup/picha_backup';

-- Export เป็น Parquet (ขนาดเล็กกว่า เหมาะกับ archive)
EXPORT DATABASE 'backup/picha_backup' (
    FORMAT      parquet,
    COMPRESSION zstd
);

ไฟล์ที่ได้ในโฟลเดอร์ backup/picha_backup/

backup/picha_backup/
├── schema.sql        ← CREATE TABLE, CREATE VIEW ทั้งหมด
├── load.sql          ← COPY statements สำหรับโหลดข้อมูลกลับ
├── transactions.csv  ← ข้อมูลแต่ละตาราง
├── stores.csv
├── customers.csv
└── ...

Import ทั้งฐานข้อมูล

IMPORT DATABASE 'backup/picha_backup';

คำสั่งนี้จะ 1. อ่าน schema.sql → สร้างตารางทั้งหมดขึ้นใหม่ 2. อ่าน load.sql → โหลดข้อมูลกลับเข้าทุกตาราง

เปรียบเทียบรูปแบบไฟล์

รูปแบบ อ่าน เขียน ขนาดไฟล์ ความเร็ว เหมาะกับ
CSV ใหญ่ ปานกลาง แลกเปลี่ยนข้อมูล, Excel
Excel (.xlsx) ปานกลาง ปานกลาง รายงาน, ผู้ใช้ทั่วไป
Parquet เล็กมาก เร็วมาก Analytics, Big Data

แนะนำ: ใช้ CSV สำหรับแลกเปลี่ยนข้อมูลทั่วไป, Parquet สำหรับเก็บข้อมูลขนาดใหญ่, Excel สำหรับส่งรายงานให้ทีมที่ไม่ได้ใช้ SQL

สรุป

บทนี้ครอบคลุมความสามารถด้านการนำเข้าและส่งออกข้อมูลของ DuckDB ซึ่งเป็นจุดเด่นสำคัญที่ช่วยให้ระบบนี้แตกต่างจากฐานข้อมูลทั่วไป โดยเฉพาะในงานวิเคราะห์ข้อมูลที่ต้องเชื่อมต่อกับไฟล์หลายรูปแบบและทำงานได้รวดเร็วภายในสภาพแวดล้อมเดียว

ในงานจริง CSV เป็นรูปแบบไฟล์ที่พบได้บ่อยที่สุด และ DuckDB สามารถอ่านได้ผ่าน read_csv() พร้อมความสามารถในการตรวจจับ schema โดยอัตโนมัติ นอกจากนี้ยังรองรับการกำหนด option ได้หลากหลาย เช่น ตัวคั่นข้อมูล encoding และค่าที่ใช้แทน NULL ทำให้เหมาะกับการนำเข้าข้อมูลจากแหล่งที่มีรูปแบบแตกต่างกัน

สำหรับไฟล์ Excel ผู้ใช้ต้องติดตั้ง excel extension ก่อนจึงจะสามารถอ่านและเขียนไฟล์ .xlsx ได้โดยตรง เมื่อเตรียมส่วนนี้เรียบร้อยแล้ว DuckDB ก็สามารถใช้เป็นเครื่องมือเชื่อมระหว่างงานวิเคราะห์ข้อมูลกับการส่งรายงานให้ทีมที่ทำงานบน Excel ได้อย่างสะดวก

ส่วน Parquet เป็นรูปแบบไฟล์แบบไบนารีที่ออกแบบมาสำหรับงาน analytics โดยเฉพาะ เนื่องจากจัดเก็บข้อมูลแบบ columnar จึงช่วยให้การอ่านข้อมูลทำได้รวดเร็วและบีบอัดข้อมูลได้มีประสิทธิภาพกว่ารูปแบบ CSV อย่างชัดเจน รูปแบบนี้จึงเหมาะกับชุดข้อมูลขนาดใหญ่และการแลกเปลี่ยนข้อมูลระหว่างทีม โดยรองรับการบีบอัดหลายแบบ เช่น zstd และ snappy

โดยสรุป คำสั่งหลักที่ใช้มีอยู่ 2 กลุ่ม ได้แก่ read_*() สำหรับอ่านไฟล์เข้ามาใช้ใน query และ COPY ... TO สำหรับส่งออกผลลัพธ์เป็นไฟล์ ทั้งสองแนวทางทำงานได้โดยตรงภายใน SQL โดยไม่จำเป็นต้องพึ่งเครื่องมือภายนอก จึงทำให้ DuckDB เป็นทางเลือกที่มีความคล่องตัวสูงสำหรับงาน data pipeline และการวิเคราะห์ข้อมูลในทางปฏิบัติ

คำถามท้ายบท

  1. ส่งออกรายชื่อสาขาทั้งหมด (store_name, branch_type, district) เรียงตามชื่อสาขา ไปเป็นไฟล์ CSV ชื่อ stores_export.csv โดยใช้ | เป็นตัวคั่น
คลิกเพื่อดูเฉลย
-- ส่งออกข้อมูลสาขาเป็นไฟล์ CSV โดยใช้ | เป็นตัวคั่น

COPY (
    SELECT
     store_name,   -- ชื่อสาขา
     branch_type,  -- ประเภทสาขา
     district      -- ย่านที่ตั้ง
    FROM stores
    ORDER BY store_name -- เรียงตามชื่อสาขา
) TO 'stores_export.csv' (
    HEADER true,   -- เพิ่มแถว header ในไฟล์
    DELIMITER '|'  -- ใช้ | เป็นตัวคั่น column
);
  1. ส่งออกสรุปรายได้รายสาขา (store_name, order_count, total_revenue) ไปเป็นไฟล์ Excel ชื่อ revenue_by_store.xlsx โดยตั้งชื่อ sheet ว่า Summary
คลิกเพื่อดูเฉลย
-- ส่งออกสรุปรายได้และจำนวนออร์เดอร์แยกตามสาขาเป็นไฟล์ Excel
INSTALL excel;
LOAD excel;

COPY (
    SELECT
        s.store_name,                                    -- ชื่อสาขา
        COUNT(*) AS order_count,                         -- จำนวนออร์เดอร์ทั้งหมด
        ROUND(SUM(t.net_sales_thb), 0) AS total_revenue -- รายได้รวม (บาท)
    FROM transactions t
    JOIN stores s ON t.store_id = s.store_id             -- เชื่อมตารางสาขาเพื่อดึงชื่อสาขา
    GROUP BY s.store_name                                -- จัดกลุ่มตามสาขา
    ORDER BY total_revenue DESC                          -- เรียงจากรายได้สูงสุดไปต่ำสุด
) TO 'revenue_by_store.xlsx' (
    FORMAT xlsx,       -- บันทึกในรูปแบบ Excel
    HEADER true,       -- เพิ่มแถว header ในไฟล์
    SHEET 'Summary'    -- ชื่อ sheet ในไฟล์ Excel
);
  1. ส่งออกตาราง transactions เป็นไฟล์ Parquet ชื่อ transactions.parquet โดยใช้ compression แบบ zstd เพื่อประหยัดพื้นที่
คลิกเพื่อดูเฉลย
COPY transactions TO 'transactions.parquet' (
    FORMAT      parquet,
    COMPRESSION zstd
);
  1. อ่านไฟล์ CSV ชื่อ new_customers.csv ที่ใช้ ; เป็นตัวคั่น มี header และค่า N/A แทน NULL แล้ว SELECT 5 แถวแรก
คลิกเพื่อดูเฉลย
-- อ่านไฟล์ CSV ตัวอย่าง 5 แถวแรก เพื่อตรวจสอบโครงสร้างและข้อมูลก่อน import

SELECT *
FROM read_csv(
    'new_customers.csv', -- ชื่อไฟล์ CSV ที่ต้องการอ่าน
    header = true,       -- แถวแรกเป็น header (ชื่อ column)
    delim  = ';',        -- ใช้ ; เป็นตัวคั่น column
    null   = 'N/A'       -- แปลงค่า 'N/A' ในไฟล์เป็น NULL
)
LIMIT 5; -- แสดงเพียง 5 แถวแรก
  1. สำรองฐานข้อมูลทั้งหมดลงโฟลเดอร์ backup/picha_2026 ในรูปแบบ Parquet พร้อม compression zstd จากนั้นเขียนคำสั่งสำหรับ restore ฐานข้อมูลกลับ
คลิกเพื่อดูเฉลย
-- ส่งออกฐานข้อมูลทั้งหมดเป็นไฟล์ Parquet พร้อม compression
EXPORT DATABASE 'backup/picha_2026' ( -- ส่งออกไปยัง folder ที่กำหนด
    FORMAT      parquet, -- บันทึกในรูปแบบ Parquet (ประหยัดพื้นที่และอ่านเร็ว)
    COMPRESSION zstd     -- บีบอัดด้วย zstd (ขนาดเล็ก ความเร็วสมดุล)
);

-- นำเข้าฐานข้อมูลที่ส่งออกไว้กลับมา (Restore)
IMPORT DATABASE 'backup/picha_2026'; -- อ่านไฟล์จาก folder เดิมที่ export ไว้