select blockchain,
sum(amount_usd) as trade_amount,
count(*) as transaction_count,
count(distinct taker) as user_count
from uniswap.trades
where block_time >= date('2022-01-01')
and block_time < date('2023-01-01')
group by 1
with transaction_summary as (
select date_trunc('day', block_time) as block_date,
blockchain,
sum(amount_usd) as trade_amount,
count(*) as transaction_count,
count(distinct taker) as user_count
from uniswap.trades
where block_time >= date('2022-01-01')
and block_time < date('2023-01-01')
group by 1, 2
)
select block_date,
blockchain,
trade_amount,
transaction_count,
user_count,
sum(trade_amount) over (partition by blockchain order by block_date) as accumulate_trade_amount,
sum(transaction_count) over (partition by blockchain order by block_date) as accumulate_transaction_count,
sum(user_count) over (partition by blockchain order by block_date) as accumulate_user_count
from transaction_summary
order by 1, 2
with user_initial_trade as (
select blockchain,
taker,
min(block_time) as block_time
from uniswap.trades
group by 1, 2
),
new_users_summary as (
select date_trunc('day', block_time) as block_date,
blockchain,
count(*) as new_user_count
from user_initial_trade
where block_time >= date('2022-01-01')
and block_time < date('2023-01-01')
group by 1, 2
),
active_users_summary as (
select date_trunc('day', block_time) as block_date,
blockchain,
count(distinct taker) as active_user_count
from uniswap.trades
where block_time >= date('2022-01-01')
and block_time < date('2023-01-01')
group by 1, 2
)
select a.block_date,
a.blockchain,
a.active_user_count,
n.new_user_count,
coalesce(a.active_user_count, 0) - coalesce(n.new_user_count, 0) as retain_user_count,
sum(new_user_count) over (partition by n.blockchain order by n.block_date) as accumulate_new_user_count
from active_users_summary a
inner join new_users_summary n on a.block_date = n.block_date and a.blockchain = n.blockchain
order by 1, 2
上面提到我们想要对比每日新增用户和每日留存用户数量及其占比情况。由于我们的查询结果已经按照区块链进行了分组,这种情况下相关可视化图表一次只能展示一项数据,无法在同一个图表中显示每日新增用户数量和每日留存用户数量这两个数据指标。这种情况下,我们可以使用Dune SQL引擎的Query of Query 功能,编写一个新的查询,使用上述查询结果作为数据源,筛选出具体的一个区块链的统计结果。因为不在需要按区块链进行分组,所以我们可以在一个图表中输出多项指标。
select block_date,
active_user_count,
new_user_count,
retain_user_count
from query_1928825 -- This points to all returned data from query https://dune.com/queries/1928825
where blockchain = '{{blockchain}}'
order by block_date
with pool_created_detail as (
select 'ethereum' as blockchain,
evt_block_time,
evt_tx_hash,
pool,
token0,
token1
from uniswap_v3_ethereum.Factory_evt_PoolCreated
union all
select 'arbitrum' as blockchain,
evt_block_time,
evt_tx_hash,
pool,
token0,
token1
from uniswap_v3_arbitrum.UniswapV3Factory_evt_PoolCreated
union all
select 'optimism' as blockchain,
evt_block_time,
evt_tx_hash,
pool,
token0,
token1
from uniswap_v3_optimism.Factory_evt_PoolCreated
union all
select 'polygon' as blockchain,
evt_block_time,
evt_tx_hash,
pool,
token0,
token1
from uniswap_v3_polygon.factory_polygon_evt_PoolCreated
)
select blockchain,
count(distinct pool) as pool_count
from pool_created_detail
where evt_block_time >= date('2022-01-01')
and evt_block_time < date('2023-01-01')
group by 1
with pool_created_detail as (
-- 此处SQL同上
),
daily_pool_summary as (
select date_trunc('day', evt_block_time) as block_date,
blockchain,
count(distinct pool) as pool_count
from pool_created_detail
group by 1, 2
)
select block_date,
blockchain,
pool_count,
sum(pool_count) over (partition by blockchain order by block_date) as accumulate_pool_count
from daily_pool_summary
where block_date >= date('2022-01-01')
and block_date < date('2023-01-01')
order by block_date
with pool_created_detail as (
-- 此处SQL同上
),
token_transfer_detail as (
select p.blockchain,
t.contract_address,
t.evt_block_time,
t.evt_tx_hash,
t."to" as pool,
cast(t.value as double) as amount_original
from erc20_arbitrum.evt_Transfer t
inner join pool_created_detail p on t."to" = p.pool
where p.blockchain = 'arbitrum'
union all
select p.blockchain,
t.contract_address,
t.evt_block_time,
t.evt_tx_hash,
t."from" as pool,
-1 * cast(t.value as double) as amount_original
from erc20_arbitrum.evt_Transfer t
inner join pool_created_detail p on t."from" = p.pool
where p.blockchain = 'arbitrum'
union all
select p.blockchain,
t.contract_address,
t.evt_block_time,
t.evt_tx_hash,
t."to" as pool,
cast(t.value as double) as amount_original
from erc20_ethereum.evt_Transfer t
inner join pool_created_detail p on t."to" = p.pool
where p.blockchain = 'ethereum'
union all
select p.blockchain,
t.contract_address,
t.evt_block_time,
t.evt_tx_hash,
t."from" as pool,
-1 * cast(t.value as double) as amount_original
from erc20_ethereum.evt_Transfer t
inner join pool_created_detail p on t."from" = p.pool
where p.blockchain = 'ethereum'
union all
select p.blockchain,
t.contract_address,
t.evt_block_time,
t.evt_tx_hash,
t."to" as pool,
cast(t.value as double) as amount_original
from erc20_optimism.evt_Transfer t
inner join pool_created_detail p on t."to" = p.pool
where p.blockchain = 'optimism'
union all
select p.blockchain,
t.contract_address,
t.evt_block_time,
t.evt_tx_hash,
t."from" as pool,
-1 * cast(t.value as double) as amount_original
from erc20_optimism.evt_Transfer t
inner join pool_created_detail p on t."from" = p.pool
where p.blockchain = 'optimism'
union all
select p.blockchain,
t.contract_address,
t.evt_block_time,
t.evt_tx_hash,
t."to" as pool,
cast(t.value as double) as amount_original
from erc20_polygon.evt_Transfer t
inner join pool_created_detail p on t."to" = p.pool
where p.blockchain = 'polygon'
union all
select p.blockchain,
t.contract_address,
t.evt_block_time,
t.evt_tx_hash,
t."from" as pool,
-1 * cast(t.value as double) as amount_original
from erc20_polygon.evt_Transfer t
inner join pool_created_detail p on t."from" = p.pool
where p.blockchain = 'polygon'
),
token_list as (
select distinct contract_address
from token_transfer_detail
),
latest_token_price as (
select contract_address, symbol, decimals, price, minute
from (
select row_number() over (partition by contract_address order by minute desc) as row_num, *
from prices.usd
where contract_address in (
select contract_address from token_list
)
and minute >= now() - interval '1' day
order by minute desc
) p
where row_num = 1
),
token_transfer_detail_amount as (
select blockchain,
d.contract_address,
evt_block_time,
evt_tx_hash,
pool,
amount_original,
amount_original / pow(10, decimals) * price as amount_usd
from token_transfer_detail d
inner join latest_token_price p on d.contract_address = p.contract_address
)
select blockchain,
sum(amount_usd) as tvl,
(sum(sum(amount_usd)) over ()) / 1e9 as total_tvl
from token_transfer_detail_amount
where abs(amount_usd) < 1e9 -- Exclude some outlier values from Optimism chain
group by 1
CTE latest_token_price 计算这些Token的当前价格。因为prices.usd中价格数据可能会有时间延迟,我们先取出最近1天内的数据,然后结合row_number() over (partition by contract_address order by minute desc)计算行号并只返回行号等于1的行,这些就是各个Token的最新价格记录。
with pool_created_detail as (
-- 此处SQL同上
),
token_transfer_detail as (
-- 此处SQL同上
),
token_list as (
-- 此处SQL同上
),
latest_token_price as (
-- 此处SQL同上
),
token_transfer_detail_amount as (
-- 此处SQL同上
),
tvl_daily as (
select date_trunc('day', evt_block_time) as block_date,
blockchain,
sum(amount_usd) as tvl_change
from token_transfer_detail_amount
where abs(amount_usd) < 1e9 -- Exclude some outlier values from Optimism chain
group by 1, 2
)
select block_date,
blockchain,
tvl_change,
sum(tvl_change) over (partition by blockchain order by block_date) as tvl
from tvl_daily
where block_date >= date('2022-01-01')
and block_date < date('2023-01-01')
order by 1, 2
with pool_created_detail as (
-- 此处SQL同上
),
token_transfer_detail as (
-- 此处SQL同上
),
token_list as (
-- 此处SQL同上
),
latest_token_price as (
-- 此处SQL同上
),
token_transfer_detail_amount as (
-- 此处SQL同上
),
top_tvl_pools as (
select pool,
sum(amount_usd) as tvl
from token_transfer_detail_amount
where abs(amount_usd) < 1e9 -- Exclude some outlier values from Optimism chain
group by 1
order by 2 desc
limit 200
)
select concat(tk0.symbol, '-', tk1.symbol) as pool_name,
sum(t.tvl) as tvl
from top_tvl_pools t
inner join pool_created_detail p on t.pool = p.pool
inner join tokens.erc20 as tk0 on p.token0 = tk0.contract_address
inner join tokens.erc20 as tk1 on p.token1 = tk1.contract_address
group by 1
order by 2 desc
limit 100