为什么我的 Alasql UDF 不能处理分组数据?

Why doesn't my Alasql UDF work with grouped data?

提问人:Sasgorilla 提问时间:5/19/2023 最后编辑:Sasgorilla 更新时间:11/15/2023 访问量:30

问:

假设我有几只猫:

interface Cat {
  name: string
  age: number
  color: string
}

我想总结每种颜色的猫的年龄。这在 (Ala)SQL 中按预期工作:

const sql = `
  SELECT name, sum(age)
  FROM ?
  GROUP BY color
`
alasql(sql, [cats])

但是,如果我写一个用户定义的总和:

import {sum} from 'lodash'
alasql.fn.mySum = function(xs) { sum(xs) }

const sql = `
  SELECT name, mySum(age)
  FROM ?
  GROUP BY color
`
alasql(sql, [cats])

则被调用,等于 。我在这里做错了什么?mySumxsundefined

JavaScript SQL AlaSQL

评论


答:

0赞 bab245 5/19/2023 #1

我不确定这是否正是您要找的,但我认为它可能看起来像:

import {sum} from 'lodash'
alasql.fn.mySum = function(xs) { return sum(xs) }
alasql(SELECT name, mySum(age) FROM ? GROUP BY color, [cats])

也许您忘记了函数中的关键字。returnmySum

评论

0赞 Sasgorilla 5/19/2023
Alasql 是一个在浏览器中运行的 Javascript 库 - 我添加了标签来帮助澄清这一点。(此答案的最后一行不是有效的 Javascript。[Javascript]
0赞 mathiasrw 11/15/2023 #2

AlaSQL 的聚合函数是针对数据集中的每一行调用的,它们通常具有每次调用都会更新的内部状态。在您的例子中,您使用的是 Lodash 的 sum 函数,该函数旨在一次处理整个数组,而不是按行工作。

若要解决此问题,必须重新定义 mySum,使其行为类似于 AlaSQL 聚合函数。

  • 初始化状态:首先初始化一个变量来保存总和。
  • 聚合函数:创建一个函数,它接受两个参数:累加器(运行总计)和当前值。使用每行的当前值更新累加器。
  • 完成函数:(可选)定义一个函数,用于在处理完所有行后完成结果。

例:

alasql.fn.mySum = function(state, age) {
switch(state) {
    case 0: // Initialization
        this.total = 0;
        break;
    case 1: // Row processing
        this.total += age;
        break;
    case 2: // Finalization
        return this.total;
}
};

const sql = `
  SELECT color, mySum(age)
  FROM ?
  GROUP BY color
`;
alasql(sql, [cats]);