无法使用 knex.js 中的连接复制 PostgresQL 查询

Posted

技术标签:

【中文标题】无法使用 knex.js 中的连接复制 PostgresQL 查询【英文标题】:Cannot replicate PostgresQL query with joins in knex.js 【发布时间】:2017-05-02 18:38:26 【问题描述】:

我正在使用以下表格/模式:

Usersid 为主,还有 emailusername 等。

Studies 有一个users 属性:一个整数数组(都是用户ID)。

问题:我想做的是找到与单个研究相关的所有用户的 ID/用户名/电子邮件。

我实际工作的 PostgresQL 查询如下(为简洁起见,模式/表名被缩短):

SELECT u.id, u.username, u.email
FROM users u
INNER JOIN studies s
  ON u.id = ANY(s.users)
WHERE s.id = 1

这将成功地为我提供一个 ID 为 1 的研究中的用户列表。

但是,我的问题在于使用 knex.js 转换此查询。我尝试了以下方法:

return knex('users')
  .select('id', 'username', 'email')
  .from('users')
  .innerJoin('studies', 'users.id', '=', 'ANY(studies.users)')
  .where('studies.id', 1);

然而,这会返回一个错误:

42P01 表 \\"studies\\" 有一个条目,但无法从这部分查询中引用它。

我也尝试了以下所有错误:

// fails
return knex('users')
  .join('studies', 'users.id', 'ANY(studies.users)')
  .select('users.id', 'users.username', 'users.email')
  .where('studies.id', 1);

// fails
return knex('users')
  .select('id', 'username', 'email')
  .from('users')
  .innerJoin('studies', function() 
     this.on('users.id', '=', 'ANY(studies.users)');
  )
  .where('studies.id', 1);

我见过this question here,但我没有看到我是如何混合显式和隐式连接的。谁能指出我正确的方向?


更新

我暂时使用knex.raw,因为我不明白链接其他方法的问题是什么。我发现它几乎不像我希望的那样可重复使用,但它仍然有效。这是我最终的结果:

async function getAllByStudy(studyId) 
  try 
    const results = await knex.raw(`
      SELECT u.id, u.username, u.email
      FROM users u
      INNER JOIN studies s
        ON u.id = ANY(s.users)
      WHERE s.id = $studyId
    `);
    return results.rows;
   catch (err) 
    return new Error(err);
  

async/await 功能允许一些不错的结构,因为knex.raw 是异步的。我现在正在解决它,但如果有人有更好的方法,请告诉我!

【问题讨论】:

无法避免使用 ANY? 我也尝试过使用数组表示法并检查ARRAY['studies.users']::integer[],但同样失败。 studies.users 是哪种数据类型?整数数组? 没错。 你可以试试onIN和UNNEST(注意:我不擅长knex) 【参考方案1】:

您没有提到 usersstudies 表(OneToOne 或 OneToMany)之间的关系。

如果您以studies 表作为开始查询,这将很容易

knex('studies')
.leftJoin('users', 'users.id', 'users.user_id')
.where('studies.id', YOUR_QUERY_ID)
.columns([
  'users.id',
  'users.username',
  'users.email'
])
.then((results) => 
  console.log(results) // array
)

编辑 1 数据库表连接-

【讨论】:

你能解释一下leftJoin吗?我不明白users.users_id 来自哪里。用户和研究之间的关系是多对多:多个用户可以在一个研究中,用户可以根据需要属于任意多个研究。我也非常感谢您的回答 - 至少它没有抛出任何错误!只返回一个空对象。 我用很少的解释表连接编辑了我的答案。如果您的研究表有正确的数据,它应该返回数组。 感谢图表!但是,我继续遇到同样的错误。

以上是关于无法使用 knex.js 中的连接复制 PostgresQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

如何将字符集添加到 Knex.js 连接字符串?

如何在 knex.js 中的“join”的“on”条件下使用“and”

使用 objection.js 或 knex.js 在 postgres 中的字符串列的 json 数组中查询

使用 Knex.js 进行多行插入

使用 Knex.js 和 PostgreSQL 设置 Docker

Knex.js 会阻止 sql 注入吗?