with profile_created as (
select json_value(vars, 'lax $.to') as user_address,
json_value(vars, 'lax $.handle') as handle_name,
replace(json_value(vars, 'lax $.handle'), '.lens', '') as short_name,
call_block_time,
output_0 as profile_id,
call_tx_hash
from lens_polygon.LensHub_call_createProfile
where call_success = true
),
multiple_profiles_addresses as (
select user_address,
count(profile_id) as profile_count
from profile_created
group by 1
order by 2 desc
)
select (case when profile_count >= 10 then '10+ Profiles'
when profile_count >= 3 then '5+ Profiles'
when profile_count = 2 then '2 Profiles'
else '1 Profile'
end) as profile_count_type,
count(user_address) as user_address_count,
sum(profile_count) as profile_count
from multiple_profiles_addresses
group by 1
select call_block_time,
call_tx_hash,
output_0 as post_id,
json_value(vars, 'lax $.profileId') as profile_id, -- Access element in json string
json_value(vars, 'lax $.contentURI') as content_url,
json_value(vars, 'lax $.collectModule') as collection_module,
json_value(vars, 'lax $.referenceModule') as reference_module,
vars
from lens_polygon.LensHub_call_post
where call_success = true
limit 10
with post_data as (
select call_block_time,
call_tx_hash,
output_0 as post_id,
json_value(vars, 'lax $.profileId') as profile_id, -- Access element in json string
json_value(vars, 'lax $.contentURI') as content_url,
json_value(vars, 'lax $.collectModule') as collection_module,
json_value(vars, 'lax $.referenceModule') as reference_module,
from lens_polygon.LensHub_call_post
where call_success = true
union all
select call_block_time,
call_tx_hash,
output_0 as post_id,
json_value(vars, 'lax $.profileId') as profile_id, -- Access element in json string
json_value(vars, 'lax $.contentURI') as content_url,
json_value(vars, 'lax $.collectModule') as collection_module,
json_value(vars, 'lax $.referenceModule') as reference_module,
from lens_polygon.LensHub_call_postWithSig
where call_success = true
),
posts_summary as (
select count(*) as total_post_count,
count(distinct profile_id) as posted_profile_count
from post_data
),
top_post_profiles as (
select profile_id,
count(*) as post_count
from post_data
group by 1
order by 2 desc
limit 1000
)
select profile_id,
post_count,
sum(post_count) over () as top_profile_post_count,
total_post_count,
posted_profile_count,
cast(sum(post_count) over () as double) / total_post_count * 100 as top_profile_posts_ratio
from top_post_profiles
inner join posts_summary on true
order by 2 desc
with post_data as (
-- Get post data from LensHub_call_post and LensHub_call_postWithSig tables
),
post_daily_summary as (
select date_trunc('day', call_block_time) as block_date,
count(*) post_count,
count(distinct profile_id) as profile_count
from post_data
group by 1
)
select block_date,
post_count,
profile_count,
sum(post_count) over (order by block_date) as accumulate_post_count
from post_daily_summary
order by block_date
with post_data as (
select call_block_time,
call_tx_hash,
output_0 as post_id,
json_value(vars, 'lax $.profileId') as profile_id, -- Access element in json string
json_value(vars, 'lax $.contentURI') as content_url,
json_value(vars, 'lax $.collectModule') as collection_module,
json_value(vars, 'lax $.referenceModule') as reference_module
from lens_polygon.LensHub_call_post
where call_success = true
and call_block_time >= now() - interval '30' day
union all
select call_block_time,
call_tx_hash,
output_0 as post_id,
json_value(vars, 'lax $.profileId') as profile_id, -- Access element in json string
json_value(vars, 'lax $.contentURI') as content_url,
json_value(vars, 'lax $.collectModule') as collection_module,
json_value(vars, 'lax $.referenceModule') as reference_module
from lens_polygon.LensHub_call_postWithSig
where call_success = true
and call_block_time >= now() - interval '30' day
)
select profile_id,
count(*) as post_count
from post_data
group by 1
order by 2 desc
limit 100
Lens的评论数据与发帖数据类似,按数据产生来源不同,分别保存在LensHub_call_comment和LensHub_call_commentWithSig表中。基于Lens协议目前的功能,用户必须已经创建了自己的Profile才能对其他人创作者对Post进行评论。在评论数据表中,是通过评论者的Profile ID来进行追踪的。同时,每个创作者的发帖,其编号是从1开始累加的。也就是说,不同创作者的发帖,其编号可能相同。我们需要将创作者的Profile ID 和其Publication ID关联起来这样才能得到唯一的编号。SQL如下:
select call_block_time,
call_tx_hash,
output_0 as comment_id, -- 评论编号
json_value(vars, 'lax $.profileId') as profile_id_from, -- 评论者的Profile ID
json_value(vars, 'lax $.contentURI') as content_url, -- 评论内容链接
json_value(vars, 'lax $.pubIdPointed') as publication_id_pointed, -- 被评论的Publication ID
json_value(vars, 'lax $.profileIdPointed') as profile_id_pointed, -- 被评论的创作者的Profile ID
json_value(vars, 'lax $.profileIdPointed') || '-' || json_value(vars, 'lax $.pubIdPointed') as unique_publication_id -- 组合生成唯一编号
from lens_polygon.LensHub_call_comment
where call_success = true
limit 10
with comment_data as (
-- get comment data from LensHub_call_comment and LensHub_call_commentWithSig tables
)
select profile_id_pointed,
publication_id_pointed,
unique_publication_id,
count(*) as comment_count
from comment_data
group by 1, 2, 3
order by 4 desc
limit 500
select call_block_time,
t."from" as collector,
c.profileId as profile_id,
c.pubId as publication_id,
cast(c.profileId as varchar) || '-' || cast(c.pubId as varchar) as unique_publication_id,
c.output_0 as collection_id
from lens_polygon.LensHub_call_collect c
inner join polygon.transactions t on c.call_tx_hash = t.hash -- 关联交易表获取用户地址
where call_block_time >= date('2022-05-18') -- Lens合约的发布日期,提升查询效率
and block_time >= date('2022-05-18')
and c.call_success = true
limit 10
select
json_query(vars, 'lax $.follower') AS follower, -- single value
json_query(vars, 'lax $.profileIds') AS profileIds, -- still string
from_hex(cast(json_extract(vars,'$.follower') as varchar)) as follower2, -- cast to varbinary
cast(json_extract(vars,'$.profileIds') as array(integer)) as profileIds2, -- cast to array
vars
from lens_polygon.LensHub_call_followWithSig
where cardinality(output_0) > 1
limit 10
读取关注详情的完整SQL代码如下:
with follow_data as (
select f.follower, p.profile_id
from (
select from_hex(cast(json_extract(vars,'$.follower') as varchar)) as follower, -- cast to varbinary
cast(json_extract(vars,'$.profileIds') as array(integer)) as profile_ids -- cast to array
from lens_polygon.LensHub_call_followWithSig
union all
select t."from" as follower,
cast(f.profileIds as array(integer)) as profile_ids
from lens_polygon.LensHub_call_follow f
inner join polygon.transactions t on f.call_tx_hash = t.hash
where call_block_time >= date('2022-05-18') -- Lens launch date
and block_time >= date('2022-05-18')
and call_success = true
) f
cross join unnest(f.profile_ids) as p(profile_id)
)
select * from follow_data
limit 100
这里需要说明一下,我们使用了cross join unnest(f.profile_ids) as p(profile_id)子句,将子查询中的数组进行拆解,并获取拆开的单个ID值。同时,因为lens_polygon.LensHub_call_follow表中的元素类型为uint256,这是一个Dune 的自定义类型,我们无法在从json字符串提取值时使用这个类型,所以我们用cast(f.profileIds as array(integer))将uint256转换为integer类型。
with follow_data as (
-- Get follow data from table LensHub_call_follow and LensHub_call_followWithSig
),
profile_follower as (
select profile_id,
count(follower) as follower_count
from follow_data
group by 1
)
select (case when follower_count >= 10000 then '10K+ Followers'
when follower_count >= 1000 then '1K+ Followers'
when follower_count >= 100 then '100+ Followers'
when follower_count >= 50 then '50+ Followers'
when follower_count >= 10 then '10+ Followers'
when follower_count >= 5 then '5+ Followers'
else '1 - 5 Followers'
end) as follower_count_type,
count(profile_id) as profile_count
from profile_follower
group by 1
with action_data as (
with post_data as (
-- get post data from relevant tables
),
comment_data as (
-- get comment data from relevant tables
),
mirror_data as (
-- get mirror data from relevant tables
)
select 'Post' as action_type, * from post_data
union all
select 'Mirror' as action_type, * from mirror_data
union all
select 'Comment' as action_type, * from comment_data
)
select action_type,
count(*) as transaction_count,
count(distinct profile_id) as profile_count
from action_data
group by 1
我们可以用相似的方法,新建一个按日期汇总每日各种操作数量的查询。示例代码如下:
with action_data as (
-- same as above query
)
select date_trunc('day', call_block_time) as block_date,
action_type,
count(*) as transaction_count
from action_data
group by 1, 2
order by 1, 2
with action_data as (
with follow_data as (
-- get follow data from relevant tables
),
collect_data as (
-- get collect data from relevant tables
)
select 'Follow' as action_type, * from follow_data
union all
select 'Collect' as action_type, * from collect_data
)