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

时间:2017-05-02 18:38:27

标签: javascript postgresql knex.js

我正在使用以下表/架构:

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功能允许一些不错的结构。我现在正在解决它,但如果有人有更好的方法,请告诉我!

1 个答案:

答案 0 :(得分:0)

你没有提到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 数据库表连接 - enter image description here