You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在jq中实现SQL风格的GROUP BY聚合函数(COUNT、SUM等)

我刚好最近在用jq处理类似的聚合需求,结合你提到的主人-宠物模型,我来一步步演示如何用jq模拟SQL里的常见聚合函数——包括COUNT、SUM、MAX、MIN、AVG,还有PostgreSQL的ARRAY_AGG。先给大家看一下我们要用的源数据:

[
  {
    "owner": "Alice",
    "pets": [
      {"name": "Mittens", "age": 3},
      {"name": "Whiskers", "age": 1}
    ]
  },
  {
    "owner": "Bob",
    "pets": [
      {"name": "Rex", "age": 5},
      {"name": "Fido", "age": 2},
      {"name": "Spot", "age": 4}
    ]
  },
  {
    "owner": "Charlie",
    "pets": [
      {"name": "Purr", "age": 2}
    ]
  }
]

1. 模拟SQL COUNT:统计每位主人的宠物数量

对应SQL逻辑:SELECT owner, COUNT(pet) FROM owners GROUP BY owner,jq里用length统计数组长度即可:

.[] | {owner: .owner, pet_count: .pets | length}

预期输出:

{"owner":"Alice","pet_count":2}
{"owner":"Bob","pet_count":3}
{"owner":"Charlie","pet_count":1}

2. 模拟SQL SUM:计算每位主人的宠物年龄总和

对应SQL逻辑:SELECT owner, SUM(pet.age) FROM owners GROUP BY owner,用map(.age)提取年龄数组后,add求和:

.[] | {owner: .owner, total_pet_age: .pets | map(.age) | add}

预期输出:

{"owner":"Alice","total_pet_age":4}
{"owner":"Bob","total_pet_age":11}
{"owner":"Charlie","total_pet_age":2}

3. 模拟SQL MAX/MIN:找出每位主人宠物的最大/最小年龄

MAX(最大年龄)

对应SQL逻辑:SELECT owner, MAX(pet.age) FROM owners GROUP BY owner,用map(.age) | max实现:

.[] | {owner: .owner, max_pet_age: .pets | map(.age) | max}

预期输出:

{"owner":"Alice","max_pet_age":3}
{"owner":"Bob","max_pet_age":5}
{"owner":"Charlie","max_pet_age":2}

MIN(最小年龄)

对应SQL逻辑:SELECT owner, MIN(pet.age) FROM owners GROUP BY owner,用map(.age) | min实现:

.[] | {owner: .owner, min_pet_age: .pets | map(.age) | min}

预期输出:

{"owner":"Alice","min_pet_age":1}
{"owner":"Bob","min_pet_age":2}
{"owner":"Charlie","min_pet_age":2}

4. 模拟SQL AVG:计算每位主人宠物的平均年龄

对应SQL逻辑:SELECT owner, AVG(pet.age) FROM owners GROUP BY owner,用总和除以数量即可,想要格式化小数可以用round(n):

.[] | {
  owner: .owner,
  avg_pet_age: ((.pets | map(.age) | add) / (.pets | length)) | round(2)
}

预期输出:

{"owner":"Alice","avg_pet_age":2}
{"owner":"Bob","avg_pet_age":3.67}
{"owner":"Charlie","avg_pet_age":2}

5. 模拟PostgreSQL ARRAY_AGG:聚合宠物名称为数组

对应SQL逻辑:SELECT owner, ARRAY_AGG(pet.name) FROM owners GROUP BY owner,直接用map(.name)提取名称数组:

.[] | {owner: .owner, pet_names: .pets | map(.name)}

预期输出:

{"owner":"Alice","pet_names":["Mittens","Whiskers"]}
{"owner":"Bob","pet_names":["Rex","Fido","Spot"]}
{"owner":"Charlie","pet_names":["Purr"]}

组合多个聚合函数

如果想一次性获取所有聚合结果,把字段合并到一个对象里即可:

.[] | {
  owner: .owner,
  pet_count: .pets | length,
  total_pet_age: .pets | map(.age) | add,
  max_pet_age: .pets | map(.age) | max,
  min_pet_age: .pets | map(.age) | min,
  avg_pet_age: ((.pets | map(.age) | add) / (.pets | length)) | round(2),
  pet_names: .pets | map(.name)
}

内容的提问来源于stack exchange,提问作者Onkeltem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:37:42