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

使用Knex结合array_agg时出现‘Expected 1 bindings, saw 0’错误的解决咨询

错误原因及修复方案

核心错误点

  1. whereIn参数格式错误
    你用模板字符串${userId}把数组转成了字符串,比如[1,2,3]变成了"[1,2,3]"。Knex解析whereIn时,会把这个字符串当成单个绑定参数,但实际你需要传入数组让Knex自动生成多个占位符,这就导致了"Expected 1 bindings, saw 0"的绑定数量不匹配错误。

  2. knex.raw用法错误
    knex.raw的第二个参数是用于SQL绑定的变量,不是多个SQL片段。你把多个ARRAY_AGG语句作为参数传给knex.raw,这不符合语法,会导致SQL解析异常,也可能间接影响绑定逻辑。

修复后的代码

knex('user')
  .leftJoin('user_has_restaurant', 'user_has_restaurant.user_id', 'user.id')
  .leftJoin('restaurant', 'user_has_restaurant.restaurant_id', 'restaurant.id')
  .select([
    'user.id AS user_id',
    'user.name AS user_name',
    // 把所有聚合语句放在一个raw里,用逗号分隔
    knex.raw(`
      ARRAY_AGG(restaurant.id) as restaurant_ids,
      ARRAY_AGG(restaurant.name) as restaurant_names,
      ARRAY_AGG(restaurant.description) as restaurant_descriptions,
      ARRAY_AGG(restaurant.website) as restaurant_websites,
      ARRAY_AGG(restaurant.created_at) as restaurant_created_ats,
      ARRAY_AGG(restaurant.updated_at) as restaurant_updated_ats
    `)
  ])
  .groupBy('user.id')
  .whereIn('user.id', userId) // 直接传入数组,不要用模板字符串

或者也可以把每个聚合字段单独用knex.raw,更清晰:

knex('user')
  .leftJoin('user_has_restaurant', 'user_has_restaurant.user_id', 'user.id')
  .leftJoin('restaurant', 'user_has_restaurant.restaurant_id', 'restaurant.id')
  .select([
    'user.id AS user_id',
    'user.name AS user_name',
    knex.raw('ARRAY_AGG(restaurant.id) as restaurant_ids'),
    knex.raw('ARRAY_AGG(restaurant.name) as restaurant_names'),
    knex.raw('ARRAY_AGG(restaurant.description) as restaurant_descriptions'),
    knex.raw('ARRAY_AGG(restaurant.website) as restaurant_websites'),
    knex.raw('ARRAY_AGG(restaurant.created_at) as restaurant_created_ats'),
    knex.raw('ARRAY_AGG(restaurant.updated_at) as restaurant_updated_ats')
  ])
  .groupBy('user.id')
  .whereIn('user.id', userId)

额外注意事项

  • 如果userId可能为空数组,建议提前做判断,避免生成WHERE user.id IN ()这种无效SQL,PostgreSQL会报错。可以加个条件:.where(function() { if (userId.length) this.whereIn('user.id', userId); })
  • ARRAY_AGG会返回包含null的数组,如果用户没有关联餐厅,所有聚合字段都会是[null]。如果要返回空数组,可以用ARRAY_AGG(restaurant.id) FILTER (WHERE restaurant.id IS NOT NULL)来过滤空值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:05:25