select block_time, hash, "from" as address, "to" as contract_address
from ethereum.transactions
where block_time >= date('2022-12-18')
limit 10
使用日期时间值
Dune SQL使用timestamp 操作符
select block_time, hash, "from" as address, "to" as contract_address
from ethereum.transactions
where block_time >= timestamp '2022-12-18 05:00:00'
limit 10
使用interval
Dune SQL使用interval '12' hour
select block_time, hash, "from" as address, "to" as contract_address
from ethereum.transactions
where block_time >= now() - interval '12' hour
limit 10
select block_time, hash, "from" as address, "to" as contract_address
from ethereum.transactions
where block_time >= date('2022-12-18') and block_time < date('2022-12-19')
and (
hash = 0x2a5ca5ff26e33bec43c7a0609670b7d7db6f7d74a14d163baf6de525a166ab10
or "from" = 0x76BE685c0C8746BBafECD1a578fcaC680Db8242E
)
select block_time, hash, "from" as address, "to" as contract_address,
cast(value / 1e9 as varchar) || ' ETH' as amount_value,
format('%,.2f', value / 1e9) || ' ETH' as amount_value_format
from ethereum.transactions
where block_time >= date('2022-12-18') and block_time < date('2022-12-19')
and (
hash = 0x2a5ca5ff26e33bec43c7A0609670b7d7db6f7d74a14d163baf6de525a166ab10
or "from" = 0x76BE685c0C8746BBafECD1a578fcaC680Db8242E
)
select evt_block_time, evt_tx_hash, "from", "to",
cast(value as double) as amount,
cast(value as decimal(38, 0)) as amount2
from erc20_ethereum.evt_Transfer
where evt_block_time >= date('2022-12-18') and evt_block_time < date('2022-12-19')
and evt_tx_hash in (
0x2a5ca5ff26e33bec43c7a0609670b7d7db6f7d74a14d163baf6de525a166ab10,
0xb66447ec3fe29f709c43783621cbe4d878cda4856643d1dd162ce875651430fc
)
select 1 as val
union all
select cast('2' as int) as val
当我们遇到类似"Error: Line 47:1: column 1 in UNION query has incompatible types: integer, varchar(1) at line 47, position 1."这种错误时,就需要处理相应字段的类型兼容问题。
转换为double类型解决数值范围溢出错误
Dune SQL 支持整数类型 int 和 bigint,但是由于EVM等区块链不支持小数导致数值经常很大,比如当我们计算gas 费的时候,就可能遇到数值溢出的错误。下面的SQL,为了故意导致错误,我们将计算的gas fee乘以1000倍了:
select hash, gas_price * gas_used * 1000 as gas_fee
from ethereum.transactions
where block_time >= date('2022-12-18') and block_time < date('2022-12-19')
order by gas_used desc
limit 10
select hash, cast(gas_price as double) * gas_used * 1000 as gas_fee
from ethereum.transactions
where block_time >= date('2022-12-18') and block_time < date('2022-12-19')
order by gas_used desc
limit 10
select hash, gas_used, gas_limit,
cast(gas_used as double) / gas_limit as gas_used_percentage
from ethereum.transactions
where block_time >= date('2022-12-18') and block_time < date('2022-12-19')
limit 10
select num from unnest(sequence(1, 10)) as t(num)
-- select num from unnest(sequence(1, 10, 2)) as t(num) -- step 2
日期序列
Duen SQL使用unnest()搭配sequence()来生成日期序列值并转换为多行记录。
Dune SQL生成日期序列的语法:
select block_date from unnest(sequence(date('2022-01-01'), date('2022-01-31'))) as s(block_date)
-- select block_date from unnest(sequence(date('2022-01-01'), date('2022-01-31'), interval '7' day)) as s(block_date)
数组查询
Dune SQL 使用cardinality()查询数组大小。
Dune SQL语法:
select evt_block_time, evt_tx_hash, profileIds
from lens_polygon.LensHub_evt_Followed
where cardinality(profileIds) = 2
limit 10
Dune SQL 数组的索引从 1 开始计数
Dune SQL访问数组元素:
select evt_block_time, evt_tx_hash, profileIds,
profileIds[1] as id1, profileIds[2] as id2
from lens_polygon.LensHub_evt_Followed
where cardinality(profileIds) = 2
limit 10
将数组元素拆分到多行记录。
Dune SQL拆分数组元素到多行:
select evt_block_time, evt_tx_hash, profileIds, tbl.profile_id
from lens_polygon.LensHub_evt_Followed
cross join unnest(profileIds) as tbl(profile_id)
where cardinality(profileIds) = 3
limit 20
Dune SQL 还有一个潜在的高级功能,就是允许针对一个已保存的查询进行查询(Query of Query)。这个功能有很多的想象空间,可简化查询逻辑,优化缓存使用等。比如,你可以将一个复杂的查询的基础部分保存为一个query,然后基于此query来进一步的汇总统计。这个功能貌似有时还不太稳定。不过大家可以试试。
-- original query: https://dune.com/queries/1752041
select * from query_1752041
where user_status = 'Retained'
-- original query: https://dune.com/queries/1752041
select * from query_1752041
where user_status = 'Churned'