我使用pg-promise
库和bluebird
进行相关查询。
我有两张桌子,a和b,看起来像这样:
| a | | b |
|-------| |-------|
| a_id | | b_id |
| prop1 | | prop2 |
| b_a |
其中b.b_a
是对a.a_id
的引用。我想选择与给定prop1
匹配的所有条目,结果应包含所有匹配的a
- 行以及每个b
的相应a
行。这应该适用于两个相关查询。两个查询都可能返回多个结果。
如果表a
只返回一行,我可以这样做:
function getResult(prop1) {
return db.task(function (t) {
return t.one("select * from a where prop1=$1", prop1)
.then(function (a) {
return t.batch([a, t.any("select * from b where b_a=$1", a.a_id)]);
})
.then(function (data) {
var a = data[0];
var bs = data[1];
bs.forEach(function (b) {
b.a = a;
});
return bs;
});
});
}
我还能够获得所有匹配b
- 多个a
的条目 - 结果如下:
function getResult(prop1) {
return db.task(function (t) {
return t.many("select * from a where prop1=$1", prop1)
.then(function (as) {
var queries = [];
as.forEach(function (a) {
queries.push(t.any("select * from b where b_a=$1", a.id));
});
return t.batch(queries); // could concat queries with as here, but there wouldn't be a reference which b row belongs to which a row
})
.then(function (data) {
// data[n] contains all matching b rows
});
});
}
但如何将这两者结合在一起?
答案 0 :(得分:3)
我是pg-promise的作者。
当您有2张牌时:Parent
- >具有1对多关系的Child
,并且您希望获得一组匹配的Parent
行,每行扩展,属性children
设置为表{中对应行的数组{1}} ...
有几种方法可以实现这一点,因为pg-promise和承诺的组合通常非常灵活。这是最短的版本:
Child
这就是我们在那里做的事情:
首先,我们查询db.task(t => {
return t.map('SELECT * FROM Parent WHERE prop1 = $1', [prop1], parent => {
return t.any('SELECT * FROM Child WHERE parentId = $1', parent.id)
.then(children => {
parent.children = children;
return parent;
});
}).then(t.batch) /* this is short for: data => t.batch(data) */
})
.then(data => {
/* data = the complete tree */
});
项,然后将每行映射到相应Parent
项的查询中,然后将其行设置为Child
并返回它。然后我们使用方法batch来解析从方法map返回的Parent
个查询数组。
任务将通过如下数组解决:
Child
<强>更新强>
查看更好的答案:JOIN table as array of results with PostgreSQL/NodeJS。