Integrations5 min read

使用 DuckDB 执行 SQL 查询

使用 SQL 查询电子表格数据及外部数据库

概述

ModelMonkey 内置了由 DuckDB 驱动的 SQL 引擎,可让您直接对电子表格数据运行 SQL 查询。您还可以查询外部数据库(PostgreSQL、BigQuery),甚至跨多个数据源进行联合查询。

当您需要对数据转换进行精确控制、执行复杂的聚合运算,或需要以自然语言难以清晰表达的方式合并来自不同来源的数据时,此功能非常实用。

Tip

您无需自己编写 SQL。只需用自然语言描述您的需求,ModelMonkey 会自动为您生成并执行相应的 SQL 查询。

SQL 查询的适用场景

当您的请求涉及以下情况时,ModelMonkey 会自动使用 SQL 查询:

复杂聚合
对大量数据行进行分组、求和、求平均值、计数或其他统计运算。

筛选与排序
根据多个条件查找特定记录,或按不同标准对大型数据集进行排序。

数据连接
将电子表格数据与外部数据库合并,或将多个工作表联合在一起。

数据转换
对数据进行重新格式化、计算新列,或以需要逐行处理的方式重构数据。

如果您希望针对某项操作使用 SQL 的精确性,也可以明确要求 ModelMonkey "使用 SQL" 或 "运行 SQL 查询"。

查询电子表格数据

您的电子表格数据可通过 sheet_range() 函数访问。该函数接受 A1 表示法引用,并将数据作为可查询的表返回。

重要要求

  • 所选范围的第一行必须包含列标题
  • 列名称从标题行中提取
  • 空标题将生成类似 "column_1"、"column_2" 等的列名

支持的范围格式

  • 完整工作表:sheet_range('Sheet1!A:Z')
  • 特定范围:sheet_range('Sales!A1:D100')
  • 包含特殊字符的命名范围会自动转义
text
-- Query all data from a sheet
SELECT * FROM sheet_range('Sheet1!A1:D100')

-- Filter and aggregate
SELECT category, SUM(amount) as total
FROM sheet_range('Sales!A1:E500')
WHERE date >= '2024-01-01'
GROUP BY category

-- Sort by multiple columns
SELECT * FROM sheet_range('Customers!A:F')
ORDER BY region ASC, revenue DESC

电子表格查询示例

查询外部数据库

如果您已配置外部数据连接,可以使用连接名称对其进行查询:

PostgreSQL
以 connection_name.schema.table 的形式引用表。默认 schema 通常为 "public"。

BigQuery
以 connection_name.dataset.table 的形式引用表。

外部数据库查询与标准 SQL 完全一致,您可以使用 DuckDB 支持的所有功能,包括连接查询、子查询、窗口函数和 CTE。

Tip

请先在"外部数据连接"面板中配置外部连接,然后再进行查询。

text
-- Query a PostgreSQL table
SELECT * FROM my_postgres.public.customers
WHERE country = 'USA'

-- Query a BigQuery table
SELECT event_date, COUNT(*) as events
FROM my_bigquery.analytics.page_views
GROUP BY event_date

-- Join PostgreSQL with BigQuery
SELECT p.name, b.total_events
FROM my_postgres.public.products p
JOIN my_bigquery.analytics.product_stats b
  ON p.id = b.product_id

外部数据库查询示例

连接电子表格与数据库数据

跨不同数据源进行联合查询是最强大的功能之一。您可以在单个查询中将电子表格数据与外部数据库合并使用。

常见应用场景

  • 用数据库中的客户数据丰富电子表格记录
  • 将本地追踪数据与数据仓库进行对比
  • 根据外部参考表验证电子表格条目
  • 将工作表中的销售数据与数据库中的产品目录合并
text
-- Join spreadsheet orders with database customers
SELECT
  s.order_id,
  s.order_date,
  s.amount,
  c.customer_name,
  c.email,
  c.tier
FROM sheet_range('Orders!A1:D500') s
JOIN my_postgres.public.customers c
  ON s.customer_id = c.id
WHERE s.amount > 1000

-- Cross-database aggregation
SELECT
  c.country,
  COUNT(*) as order_count,
  SUM(s.amount) as total_sales
FROM sheet_range('Sales!A1:C1000') s
JOIN my_postgres.public.customers c
  ON s.customer_id = c.id
GROUP BY c.country
ORDER BY total_sales DESC

跨数据源连接查询示例

查询输出选项

查询结果可通过两种方式呈现:

内联结果(默认)
结果直接返回至 ModelMonkey 进行分析和推理。这适用于探索性查询,即您希望先了解数据再决定如何处理的场景。

  • 默认最多返回 20 行(可配置至最多 100 行)
  • 包含列类型及元数据
  • 适合快速数据探索

输出至工作表
结果直接写入电子表格中的新工作表。当您希望保留查询结果以供后续使用时,此方式非常实用。

  • 以您指定的名称创建新工作表
  • 包含所有行(无行数限制)
  • 自动添加标题行
  • 非常适合创建报表或暂存数据

Tip

向 ModelMonkey 请求"将结果保存到新工作表"或"将输出写入名为 Results 的工作表",即可使用工作表输出模式。

数据类型处理

ModelMonkey 会自动从您的电子表格数据中推断列类型:

支持的类型

  • 数字:整数和小数将被检测并作为数值类型处理
  • 布尔值:TRUE/FALSE 值将被识别为布尔类型
  • 文本:其他所有内容均作为文本(VARCHAR)处理
  • 日期:单元格中的日期值通常作为文本处理;请使用 SQL 日期函数对其进行解析

类型推断过程
ModelMonkey 会对数据的前几行进行采样,以确定每列的适当类型。如果某列包含混合类型,则默认为文本类型以避免数据丢失。

text
-- Parse date strings in queries
SELECT
  order_id,
  strptime(order_date, '%Y-%m-%d') as parsed_date,
  amount
FROM sheet_range('Orders!A1:C100')
WHERE strptime(order_date, '%Y-%m-%d') >= DATE '2024-01-01'

-- Cast numeric strings
SELECT
  product_name,
  CAST(price AS DOUBLE) as numeric_price
FROM sheet_range('Products!A1:B50')

数据类型处理示例

性能注意事项

查询执行

  • 查询超时时间为 30 秒
  • 出于安全考虑,最大结果集为 16,384 行
  • 大型电子表格范围将被加载到内存中进行查询

最佳实践

  • 指定精确范围,而非整列(例如使用 A1:D500 而非 A:D)
  • 使用 WHERE 子句提前过滤数据,减少处理量
  • 对于非常大的数据集,考虑使用工作表输出以避免内存问题
  • 为大型外部数据库表建立索引以加速连接查询

缓存
查询结果不会在请求之间缓存。每次查询都会重新读取当前电子表格数据,确保您始终获取最新值。

Warning

非常大的范围(数万行)可能会降低查询执行速度。对于大规模分析,请考虑过滤数据或使用外部数据库。

支持的 SQL 功能

ModelMonkey 通过 DuckDB 支持多种 SQL 功能:

标准操作

  • SELECT、FROM、WHERE、ORDER BY、LIMIT
  • GROUP BY 与聚合函数(SUM、COUNT、AVG、MIN、MAX 等)
  • DISTINCT 和 HAVING 子句
  • UNION、INTERSECT、EXCEPT

连接查询

  • INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN
  • 交叉连接和自连接
  • 多表连接

高级功能

  • 子查询和 CTE(WITH 子句)
  • 窗口函数(ROW_NUMBER、RANK、LAG、LEAD 等)
  • CASE 表达式
  • 字符串函数、日期函数、数学函数

不支持的功能

  • INSERT、UPDATE、DELETE(查询为只读)
  • CREATE TABLE、ALTER TABLE(不支持 schema 修改)
  • 存储过程或用户自定义函数

查询示例

以下是一些您可能会用到的实用 SQL 查询示例:

text
-- Monthly sales summary
SELECT
  strftime(strptime(date, '%Y-%m-%d'), '%Y-%m') as month,
  COUNT(*) as num_orders,
  SUM(amount) as total_revenue,
  AVG(amount) as avg_order_value
FROM sheet_range('Orders!A1:D1000')
GROUP BY month
ORDER BY month DESC

-- Find duplicate entries
SELECT email, COUNT(*) as count
FROM sheet_range('Contacts!A1:E500')
GROUP BY email
HAVING COUNT(*) > 1

-- Top customers by spending
SELECT
  customer_id,
  SUM(amount) as total_spent,
  COUNT(*) as num_orders
FROM sheet_range('Orders!A1:D1000')
GROUP BY customer_id
ORDER BY total_spent DESC
LIMIT 10

-- Running total with window function
SELECT
  date,
  amount,
  SUM(amount) OVER (ORDER BY date) as running_total
FROM sheet_range('Transactions!A1:C100')

实用 SQL 查询示例

故障排除

"列未找到"错误

  • 检查标题行是否包含预期的列名
  • 列名区分大小写
  • 列名中的空格可以使用,但在复杂查询中可能需要加引号

"范围无效"错误

  • 确认工作表名称拼写正确
  • 确保该范围存在且包含数据
  • 检查工作表名称中是否有需要转义的特殊字符

"查询超时"错误

  • 简化查询或缩小数据范围
  • 添加 WHERE 子句以提前过滤数据
  • 对于大型结果集,考虑使用工作表输出

"连接未找到"错误

  • 确认外部连接名称正确
  • 检查"外部数据连接"面板中该连接是否处于活动状态
  • 确认您有权访问该外部数据库

空结果或意外结果

  • 检查数据类型是否与 WHERE 条件匹配
  • 确认日期格式与电子表格中的格式一致
  • 检查文本数据中是否存在前导/尾随空格