PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

obtenir la table JOIN en tant que tableau de résultats avec PostgreSQL/NodeJS

C'est facile à faire avec 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);
    });

Comme ci-dessus, mais en utilisant ES7 async /await syntaxe :

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 :carte, quelconque, tâche, lot

Questions connexes :

  • Obtenez un arbre parents + enfants avec pg-promise
  • Tâche conditionnelle avec pg-promise

Et si vous souhaitez n'utiliser qu'une seule requête, utilisez la syntaxe PostgreSQL 9.4 et versions ultérieures pour effectuer les opérations suivantes :

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

Et alors votre exemple de pg-promesse serait :

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

Et vous voudrez certainement conserver ces requêtes complexes dans des fichiers SQL externes. Voir Fichiers de requête.

Conclusion

Le choix entre les deux approches présentées ci-dessus doit être basé sur les exigences de performance de votre application :

  • L'approche de requête unique est plus rapide, mais est quelque peu difficile à lire ou à étendre, car elle est assez détaillée
  • L'approche multi-requêtes est plus facile à comprendre et à étendre, mais elle n'est pas très performante en raison du nombre dynamique de requêtes exécutées.

MISE À JOUR-1

La réponse connexe suivante offre plus d'options, en concaténant les requêtes enfants, ce qui améliorera considérablement les performances :combiner les requêtes de boucle imbriquées au résultat parent pg-promise.

MISE À JOUR-2

Un autre exemple ajouté, utilisant ES7 async /await approche.