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

Elixir中Zip映射SQL查询结果生成按年份分组的数据结构

Elixir SQL查询结果转结构化分组数据实现

方案1:匹配你原有思路的实现(先转关键字列表再分组)

你的Enum.zip思路完全可行,注意关键字列表的键需要是原子类型,所以先把字符串格式的列名转为原子即可:

# 1. 预处理列名:字符串转原子
columns = Enum.map(results.columns, &String.to_atom/1)

# 2. 逐行将列名和数据配对,生成关键字列表格式的行数据
kw_rows =
  Enum.map(results.rows, fn row ->
    Enum.zip(columns, row)
  end)

# 3. 按year字段分组
grouped_result = Enum.group_by(kw_rows, &Keyword.get(&1, :year))

执行后得到的grouped_result结构完全匹配预期:

%{
  2018 => [
    [tour_id: 1, name: "asia", year: 2018, num_shows: 4, num_cities: 4, num_festivals: 3, num_countries: 3],
    [tour_id: 2, name: "north america", year: 2018, num_shows: 39, num_cities: 17, num_festivals: 2, num_countries: 2],
    [tour_id: 3, name: "europe", year: 2018, num_shows: 13, num_cities: 12, num_festivals: 9, num_countries: 10],
    [tour_id: 4, name: "las vegas shows", year: 2018, num_shows: 3, num_cities: 1, num_festivals: 0, num_countries: 1]
  ],
  2022 => [
    [tour_id: 5, name: "tour", year: 2022, num_shows: 13, num_cities: 10, num_festivals: 4, num_countries: 2]
  ]
}

方案2:更高效的单遍历实现

不需要单独生成中间的全量关键字列表,可以直接在group_by阶段同时完成行格式转换和分组,减少一次全量数组遍历,数据量大时性能更好:

columns = Enum.map(results.columns, &String.to_atom/1)

grouped_result =
  Enum.group_by(
    results.rows,
    # 分组键提取逻辑
    fn row ->
      row |> Enum.zip(columns) |> Keyword.get(:year)
    end,
    # 分组后的值转换逻辑
    fn row ->
      Enum.zip(columns, row)
    end
  )

注意事项

如果你的查询列名是动态生成、来自不可信的用户输入,不要使用String.to_atom/1(原子不会被垃圾回收,动态生成大量原子会导致内存泄漏),这种场景推荐用字符串键的Map替代关键字列表:

grouped_result =
  Enum.group_by(
    results.rows,
    fn row ->
      row |> Enum.zip(results.columns) |> Map.new() |> Map.get("year")
    end,
    fn row ->
      Map.new(Enum.zip(results.columns, row))
    end
  )

内容的提问来源于stack exchange,提问作者I. Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:27:32