sql >> Base de Datos >  >> RDS >> PostgreSQL

obtener la tabla JOIN como matriz de resultados con PostgreSQL/NodeJS

Esto es fácil de hacer con 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);
    });

Lo mismo que arriba, pero usando ES7 async /await sintaxis:

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, cualquiera, tarea, lote

Preguntas relacionadas:

  • Obtenga un árbol de padres e hijos con pg-promise
  • Tarea condicional con pg-promise

Y si desea usar solo una sola consulta, entonces, con la sintaxis de PostgreSQL 9.4 y versiones posteriores, puede hacer lo siguiente:

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

Y entonces tu ejemplo de pg-promise sería:

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);

Y definitivamente querrá mantener consultas tan complejas en archivos SQL externos. Ver archivos de consulta.

Conclusión

La elección entre los dos enfoques presentados anteriormente debe basarse en los requisitos de rendimiento de su aplicación:

  • El enfoque de consulta única es más rápido, pero algo difícil de leer o ampliar, ya que es bastante detallado
  • El enfoque de consultas múltiples es más fácil de comprender y ampliar, pero no es bueno para el rendimiento, debido a la cantidad dinámica de consultas ejecutadas.

ACTUALIZACIÓN-1

La siguiente respuesta relacionada ofrece más opciones, mediante la concatenación de consultas secundarias, lo que brindará un rendimiento mucho mejor:combine consultas de bucle anidado con el resultado principal pg-promise.

ACTUALIZACIÓN-2

Otro ejemplo agregado, usando ES7 async /await acercamiento.