获得pg承诺的父母+子树

时间:2016-06-06 18:19:08

标签: javascript postgresql pg-promise

我使用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
            });
    });
}

但如何将这两者结合在一起?

1 个答案:

答案 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

API参考:mapbatch

<强>更新

查看更好的答案:JOIN table as array of results with PostgreSQL/NodeJS