sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQL/NodeJSを使用して結果の配列としてJOINテーブルを取得します

    これは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 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を使用した条件付きタスク

    また、単一のクエリのみを使用する場合は、PostgreSQL9.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-promiseの例は次のようになります:

    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ファイルに保持したいと思うでしょう。クエリファイルを参照してください。

    結論

    上記の2つのアプローチのどちらを選択するかは、アプリケーションのパフォーマンス要件に基づく必要があります。

    • 単一クエリのアプローチは高速ですが、読みやすく、拡張するのがやや難しく、かなり冗長です
    • マルチクエリアプローチは理解と拡張が容易ですが、実行されるクエリの数が動的であるため、パフォーマンスには優れていません。

    更新-1

    次の関連する回答は、子クエリを連結することにより、より多くのオプションを提供します。これにより、パフォーマンスが大幅に向上します。ネストされたループクエリを親の結果pg-promiseに結合します。

    UPDATE-2

    ES7 asyncを使用して追加された別の例 /待つ アプローチ。



    1. 特定の値がSQLServer(T-SQL)でマップされるパーティションを見つける

    2. Laravelの移行でタイムスタンプ列のデフォルト値を現在のタイムスタンプに設定するにはどうすればよいですか?

    3. SQL Serverですべての信頼できない外部キー制約を返す方法(T-SQLの例)

    4. SQL ServerでSAアカウントを無効にする(T-SQLの例)