Това е лесно да се направи с pg-promise:
function buildTree(t) {
const v = q => t.any('SELECT id, value FROM votes WHERE question_id = $1', q.id)
.then(votes => {
q.votes = votes;
return q;
});
return t.map('SELECT * FROM questions', undefined, v).then(a => t.batch(a));
}
db.task(buildTree)
.then(data => {
console.log(data); // your data tree
})
.catch(error => {
console.log(error);
});
Същото като по-горе, но използвайки ES7 async
/await
синтаксис:
await db.task(async t => {
const questions = await t.any('SELECT * FROM questions');
for(const q of questions) {
q.votes = await t.any('SELECT id, value FROM votes WHERE question_id = $1', [q.id]);
}
return questions;
});
// method "task" resolves with the correct data tree
API:карта, всяка, задача, партида
Свързани въпроси:
- Вземете дърво родители + деца с pg-promise
- Условна задача с pg-promise
И ако искате да използвате само една заявка, тогава с помощта на PostgreSQL 9.4 и по-нов синтаксис можете да направите следното:
SELECT json_build_object('id', q.id, 'content', q.content, 'votes',
(SELECT json_agg(json_build_object('id', v.id, 'value', v.value))
FROM votes v WHERE q.id = v.question_id))
FROM questions q
И тогава вашият пример за pg-обещание би бил:
const query =
`SELECT json_build_object('id', q.id, 'content', q.content, 'votes',
(SELECT json_agg(json_build_object('id', v.id, 'value', v.value))
FROM votes v WHERE q.id = v.question_id)) json
FROM questions q`;
const data = await db.map(query, [], a => a.json);
И определено ще искате да запазите такива сложни заявки във външни SQL файлове. Вижте файлове със заявки.
Заключение
Изборът между двата подхода, представени по-горе, трябва да се основава на изискванията за производителност на вашето приложение:
- Подходът с една заявка е по-бърз, но е малко труден за четене или разширяване, тъй като е доста подробен
- Подходът с множество заявки е по-лесен за разбиране и разширяване, но не е страхотен за производителност поради динамичния брой изпълнени заявки.
АКТУАЛИЗИРАНЕ-1
Следният свързан отговор предлага повече опции чрез обединяване на дъщерни заявки, което ще даде много подобрена производителност:Комбинирайте заявки за вложен цикъл към родителски резултат pg-promise.
АКТУАЛИЗИРАНЕ-2
Добавен е друг пример, използващ ES7 async
/await
подход.