PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

obter tabela JOIN como array de resultados com PostgreSQL/NodeJS


Isso é fácil de fazer com 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);
    });

O mesmo que acima, mas usando ES7 async /await sintaxe:
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:mapa, qualquer, tarefa, lote

Perguntas relacionadas:
  • Obtenha uma árvore de pais + filhos com pg-promise
  • Tarefa condicional com pg-promise

E se você quiser usar apenas uma única consulta, usando a sintaxe do PostgreSQL 9.4 e posterior, você pode fazer o seguinte:
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

E então seu exemplo pg-promise seria:
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);

E você definitivamente vai querer manter essas consultas complexas em arquivos SQL externos. Consulte Arquivos de consulta.

Conclusão


A escolha entre as duas abordagens apresentadas acima deve ser baseada nos requisitos de desempenho de sua aplicação:
  • A abordagem de consulta única é mais rápida, mas é um pouco difícil de ler ou estender, sendo bastante detalhada
  • A abordagem de várias consultas é mais fácil de entender e estender, mas não é ótima para o desempenho, devido ao número dinâmico de consultas executadas.

ATUALIZAÇÃO-1

A resposta relacionada a seguir oferece mais opções, concatenando consultas filhas, o que proporcionará um desempenho muito melhor:Combine consultas de loop aninhado ao resultado pai pg-promise.

ATUALIZAÇÃO-2

Outro exemplo adicionado, usando ES7 async /await abordagem.