Neo4j如何合并查询 单行返回矿工时段奖励与总奖励
实现目标
单条Cypher语句按行返回三类数据,输出格式为(矿工名称, 指定时间范围内奖励值, 全周期累计总奖励值),示例输出:
Binance 1500 100000 Slush 1000 29900000
原有查询的问题
你之前写的两条独立查询存在两个共性问题:
WITH阶段保留了b.time字段,后续sum()聚合会按「矿工+块时间」双维度分组,无法得到单矿工维度的正确奖励求和结果- 分开查询后需要手动对齐矿工数据,效率低且容易出现漏匹配、错匹配问题
可直接运行的实现语句
用条件聚合即可单次遍历完成两个维度的统计,性能远高于两次查询后做结果关联:
// 提前解析时间范围的秒级时间戳,避免逐行重复计算 WITH apoc.date.parse("2021-04-01 05:29:58", 's') AS rangeStart, apoc.date.parse("2021-04-01 08:15:45", 's') AS rangeEnd MATCH (m:Miner)-[rel:GUESSED]->(b:Block) // 提前解析当前块的时间戳 WITH m, rel, rangeStart, rangeEnd, apoc.date.parse(b.time, 's') AS blockTs // 按矿工单维度分组聚合 RETURN m.name AS 矿工名称, SUM(CASE WHEN blockTs >= rangeStart AND blockTs <= rangeEnd THEN rel.reward ELSE 0 END) AS 时间范围内奖励值, SUM(rel.reward) AS 总奖励值
补充说明
- 如果不需要展示时间范围内无出块的矿工,在
RETURN前增加WHERE 时间范围内奖励值 > 0即可过滤 - 所有固定时间值提前解析、块时间提前解析的写法,能避免聚合阶段重复调用日期解析函数,在区块数据量较大时查询速度会有明显提升
- 聚合阶段不要额外携带块高度、块时间这类非矿工维度的字段,否则会拆分聚合粒度,导致求和结果错误
内容的提问来源于stack exchange,提问作者Traxanios
相关产品推荐
相关产品推荐

