【问题标题】:Cannot replicate PostgresQL query with joins in knex.js无法使用 knex.js 中的连接复制 PostgresQL 查询
【发布时间】: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 是哪种数据类型?整数数组?
  • 没错。
  • 你可以试试onINUNNEST(注意:我不擅长knex)

标签: javascript postgresql knex.js


【解决方案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 来自哪里。用户和研究之间的关系是多对多:多个用户可以在一个研究中,用户可以根据需要属于任意多个研究。我也非常感谢您的回答 - 至少它没有抛出任何错误!只返回一个空对象。
  • 我用很少的解释表连接编辑了我的答案。如果您的研究表有正确的数据,它应该返回数组。
  • 感谢图表!但是,我继续遇到同样的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-03
  • 2016-03-28
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
  • 2016-07-13
相关资源
最近更新 更多