sql >> Databasteknik >  >> RDS >> PostgreSQL

få JOIN-tabellen som en rad resultat med PostgreSQL/NodeJS

Detta är lätt att göra med 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);
    });

Samma som ovan, men med ES7 async /await syntax:

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:map, any, task, batch

Relaterade frågor:

  • Skaffa ett föräldrar + barn-träd med pg-löfte
  • Villkorlig uppgift med pg-promise

Och om du bara vill använda en enda fråga kan du göra följande med PostgreSQL 9.4 och senare syntax:

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

Och sedan skulle ditt exempel på pg-löfte vara:

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

Och du kommer definitivt att vilja behålla sådana komplexa frågor i externa SQL-filer. Se Frågefiler.

Slutsats

Valet mellan de två metoderna som presenteras ovan bör baseras på prestandakraven för din ansökan:

  • Single-query-metoden är snabbare, men är något svår att läsa eller utöka, eftersom den är ganska utförlig
  • Multi-frågemetoden är lättare att förstå och utöka, men den är inte bra för prestanda, på grund av det dynamiska antalet exekverade frågor.

UPPDATERING-1

Följande relaterade svar erbjuder fler alternativ genom att sammanfoga underordnade frågor, vilket ger en mycket förbättrad prestanda:Kombinera kapslade loopfrågor till överordnat resultat pg-promise.

UPPDATERING-2

Ett annat exempel har lagts till med ES7 async /await tillvägagångssätt.



  1. Tillägget mysqli saknas, phpmyadmin fungerar inte

  2. Hur gör jag en bulkinfogning i mySQL med node.js

  3. En guide för att distribuera TimescaleDB med Docker

  4. Skillnad mellan tabellfunktion och rörledningsfunktion?