【发布时间】:2017-05-02 18:38:26
【问题描述】:
我正在使用以下表格/模式:
Users 以 id 为主,还有 email、username 等。
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 是哪种数据类型?整数数组?
-
没错。
标签: javascript postgresql knex.js