别再让 Excel 毁了你下班前的灵感

白发任 笔记 63

先来三个灵魂拷问

  1. 你上一次把 ADS 表导出 Excel 做探查,是不是卡到风扇起飞?

  2. 你上一次 vlookup 三张百万行 CSV,是不是蓝屏死机?

  3. 你上一次把 Excel 粘给老板,是不是被问“能不能换个格式,我要透视”?

如果你都点头,那恭喜你——你已经在做“二次分析”了
而二次分析,正是DuckDB在今天依旧值得被数据人放进工具箱的最大理由。

一、闲谈

1.1 什么是二次分析

维度一次加工二次分析
位置数仓/Hadoop/Spark本地电脑
产出dwd/dws/ads 表业务问题的答案
工具hive/spark/flink等excel/Python/r
量级TB级GB及以下
目标口径对齐与沉淀灵活探查与试错

一句话总结:数仓把数据做对,DuckDB把数据做活

1.2 为什么能赢 Excel

维度Excel 2021DuckDB 1.3
单文件上限1,048,576 行无硬性限制(受内存)
CSV 读取慢、类型推断错GB/s+、自动推断
SQL 支持PowerQuery 半吊子完整 sql:2016
多表关联vlookup标准 JOIN
窗口函数不支持全支持
可脚本化VBAPython/R/CLI等
结果导出xlsx/csv/txtparquet/json/xlsx等

ps: 表格数据来自 AI 总结

另外在文件读取上,DuckDB 支持 parquet/avro/xlsx/csv 等文件自动推断,包括文件类型和 schema 推断

二、上手

2.1 安装

通用脚本安装


SHELL
curl https://install.duckdb.org | sh


点击查看更多安装方式: https://duckdb.org/docs/installation/?version=stable&environment=cli&platform=macos&download_method=direct

不会装?那直接使用 wasm 版本吧!!!点击前往:https://shell.duckdb.org/(注意数据安全问题哦)

2.2 数据

使用 COVID-19 流行病学公开数据中的

  1. 各国/地区每日疫情核心指标,包含:地区、确诊人数、死亡人数等点击下载:https://storage.googleapis.com/covid19-open-data/v3/epidemiology.csv

  2. 各国/地区人口、面积等静态数据,点击下载: https://storage.googleapis.com/covid19-open-data/v3/demographics.csv

schema等相关信息访问github仓库: https://github.com/GoogleCloudPlatform/covid-19-open-data

2.3 分析

虚拟一个分析场景:
找出过去 30 天内,每百万人口新增确诊最多的前 10 个国家,并给出它们的死亡率(新增死亡 ÷ 新增确诊)与 确诊率(新增确诊 ÷ 人口 × 1,000,000)
如果使用 Excel,嗯…我不会…AI说可以。

个人认为做数据分析最好的形态就是 notebook,一次尝试一个cell清晰简洁。使用duckdb -ui开启它会自动跳转到浏览器,默认地址http://localhost:4213/

别再让 Excel 毁了你下班前的灵感-第1张图片-多梦笔记

新建 notebook -> add cell -> 写sql


SQL
- 假设 epidemiology.csv 和 demographics.csv 已下载到同目录
-- epidemiology.csv 字段: date, country_code, new_confirmed, new_deceased
-- demographics.csv 字段: country_code, population

WITH last30 AS (
    -- 读取原始指标数据,duckdb会自动识别首行和 schema
    SELECT location_key, new_confirmed, new_deceased
    FROM './epidemiology.csv'
    WHERE date between STRPTIME('2021-05-01', '%Y-%m-%d') - INTERVAL 30 DAY and STRPTIME('2021-05-01', '%Y-%m-%d')
),
agg30 AS (
    -- 统计每个城市的确诊、死亡人数
    SELECT
        location_key,
        SUM(new_confirmed)  AS new_confirmed_30d,
        SUM(new_deceased)   AS new_deceased_30d
    FROM last30
    GROUP BY location_key
),
pop AS (
    -- 读取原始维度数据,duckdb会自动识别首行和 schema
    SELECT location_key, population
    FROM './demographics.csv'
)
SELECT
    p.location_key,
    -- 每百万人口新增确诊
    ROUND(new_confirmed_30d / population * 1000000, 2) AS confirmed_per_million,
    -- 死亡率
    ROUND(CAST(new_deceased_30d AS DOUBLE) / NULLIF(new_confirmed_30d, 0), 4) AS fatality_rate,
    -- 原始 30 天新增确诊
    new_confirmed_30d
FROM agg30 a
JOIN pop p on a.location_key = p.location_key
WHERE population > 0
ORDER BY confirmed_per_million DESC
LIMIT 10;


执行结果如下:

别再让 Excel 毁了你下班前的灵感-第2张图片-多梦笔记

仅500毫秒即可返回结果,同时右侧窗口展示指标的数据分布。

如果先将 csv 写入 duckdb 内部表速度将更快,因为它是列存

三、小结

DuckDB 的能力远不止如此,如果你有一些“奇怪”的权限甚至可以直接读 hive 的分区
例如:orders 是一张二级分区的表


SHELL
orders
├── year=2021
│    ├── month=1
│    │   ├── file1.parquet
│    │   └── file2.parquet
│    └── month=2
│        └── file3.parquet
└── year=2022
     ├── month=11
     │   ├── file4.parquet
     │   └── file5.parquet
     └── month=12
         └── file6.parquet


可以使用下面的sql读取且支持分区裁剪


SQL
SELECT *
FROM read_parquet('orders/*/*/*.parquet', hive_partitioning = true)
WHERE year = 2021 and month = 1;


同时 DuckDB 的 Extension 机制,让 DuckDB 支持读取 Iceberg、RDBMS、S3 甚至可以做 FTS(full-text search)和 Embedding Stores

总之:别再让 Excel 毁了你下班前的灵感,在二次分析这条赛道,DuckDB 不是“单机玩具”,而是“本地 OLAP 火箭”


分享到:

标签: Excel DuckDB 二次分析