Dune Query 入门教程及Solwallet转账追踪实践Ⅰ
介绍
聊到链上数据分析,Dune Analytics 几乎是个绕不开的工具。它把链上数据用 SQL 语言组织起来,让查询、分析、可视化都变得相当直接——尤其是对那些已经熟悉数据库查询的人来说,上手门槛并不高。这篇文章会从 Dune 的基础用法讲起,然后通过一个 Solana 链上转账追踪的实际案例,带你走一遍完整的查询实践。干货不少,建议边看边敲。
Data Explorer 功能介绍
在动手写 SQL 之前,有个东西必须先用熟:左侧的
Data Explorer
transactions 表,就能看到 block_time、pre_token_balances 这些字段——这些信息直接决定了你能怎么写查询条件。
- 浏览不同链的数据集:以太坊、Solana、Polygon 等等。
- 查看每张表的字段和数据类型,避免写错字段名或类型。
- 用搜索过滤功能快速定位你需要的表或字段。
说白了,Data Explorer 就是你的“地图”,搞清楚地图再上路,效率完全不一样。

基础语法
Dune 用的是 Trino 语法(以前叫 Presto),跟 MySQL 有些区别,但大部分基础 SQL 逻辑是通用的。下面列出几个高频关键词,看看它们具体怎么用:
- :定义公用表表达式(CTE),把复杂查询拆成几步,可读性大大提升。
WITH
- :指定要返回的列。
SELECT
- :指定数据来自哪张表。
FROM
- :加过滤条件,精准圈出你要的数据。
WHERE
- :把数组字段里的每个元素展开成独立的一行——这个在链上数据里尤其常见。
UNNEST
- :给字段或表起个别名,方便后续引用。
AS
举个例子,如果想查 Solana 链上最近 7 天的所有交易:
SELECT *
FROM solana.transactions
WHERE block_time >= NOW() - INTERVAL '7' DAY;
- 这里
SELECT *表示返回所有列。 FROM solana.transactions指定了数据源。WHERE过滤出 block_time 在最近 7 天内的记录。
联合用法和基础 UNNEST
链上数据里有很多字段是数组形态——比如一笔交易可能涉及多个代币余额的变化。这时候 UNNEST 就是主角了。它的作用是把数组里的每个元素拆成单独一行,这样你就能逐条分析每个元素的内容。
假设我们要查某个特定钱&包地址在交易中作为“发送前持有人”出现的记录:
SELECT t.block_time, pre.owner
FROM solana.transactions t,
UNNEST(t.pre_token_balances) AS pre
WHERE pre.owner = '6EDJ7JuynXSPaMvufzAX4swSRJZXv6uPi4s6jmo33xj5';
UNNEST(t.pre_token_balances) AS pre把pre_token_balances数组展开,每一行用别名pre表示。- 然后在
WHERE里筛选出owner等于目标地址的记录。
这个查询实践项目
下面来看一个实际项目:追踪 Solana 链上某个特定链下地址的代币转账。整个查询用 CTE 分层组织,每一步聚焦一个任务,最终输出从“From”到“To”的转账记录。
WITH filtered_transactions AS (
SELECT *
FROM solana.transactions t
WHERE block_time >= NOW() - INTERVAL '7' DAY
),
wallet_related_transactions AS (
SELECT *
FROM filtered_transactions t,
UNNEST(t.pre_token_balances) AS pre
WHERE pre.owner = '6EDJ7JuynXSPaMvufzAX4swSRJZXv6uPi4s6jmo33xj5'
),
token_transfers AS (
SELECT
t.block_time,
pre.owner AS "From",
post.owner AS "To",
post.mint AS "Token",
pre.amount AS "Pre_Amount",
post.amount AS "Post_Amount"
FROM
wallet_related_transactions t,
UNNEST(t.pre_token_balances) AS pre,
UNNEST(t.post_token_balances) AS post
WHERE
pre.owner = '6EDJ7JuynXSPaMvufzAX4swSRJZXv6uPi4s6jmo33xj5'
AND post.owner IS NOT NULL
AND post.mint = 'BYcs8bjoGv6m4LkRrpEDVbJvPESvP9A1migRmaDApump'
)
SELECT
block_time,
"From",
"To",
"Token",
"Pre_Amount",
"Post_Amount"
FROM
token_transfers
ORDER BY
block_time DESC
LIMIT 1000;
这个查询的过程
- 第一步,
filtered_transactions只取最近 7 天的数据,缩小数据范围。 - 第二步,
wallet_related_transactions通过UNNEST将 pre_token_balances 展开,并过滤出只包含目标地址的交易。 - 第三步,
token_transfers再展开 post_token_balances,同时加上代币合约地址的条件,最终得到每一笔转账的详细信息:时间、发送方、接收方、代币种类、转账前后余额。
这种用多个 CTE 逐步过滤的思路,在链上数据分析里非常实用——既能保证每一步逻辑清晰,也方便后续调试和扩展。
结论
总结下来,Dune Analytics 真正把链上数据变成了可交互、可查询的数据库。只要你掌握基础的 SQL 语法,再加上 UNNEST 这种处理数组的利器,就能实现各种链上行为追踪——比如监控某个地址的资金流向、分析代币的流动性变化等等。关键还是先把数据范围收敛到真正关注的信息上,避免全表扫描浪费算力。希望这次的实战拆解能给你一些启发,用 Dune 把区块链数据这块“黑箱”真正打开。