SQL join vs subquery :ゲームチェンジャー


複数のテーブルを含むSQLクエリを構築するときは、常にテーブルの結合やサブクエリの使用についての一定の議論があります.
すべての方法に長所と短所があります.私の自然な選択はテーブルに加わることです.私はそれを維持し、読みやすくなります.しかし、1つのユースケースがあります、そこで、私は確実に結合の上に副質問を支持します.
我々が2つのデータモデル、ポストとコメントを持っているブログシステムを構築していると言いましょう.つの関係は、一つから多くです.すべてのポストのために、多くのコメントがあることができます.
今、私たちはトップ3の最新のコメントと一緒にトップ10の最新のポストを返すエンドポイントを構築したいと思います.
我々の頭に来るかもしれない最初の考えはトップ10のポストのために最初に質問することです、そして、我々はコメントを問い合わせることができます.また、2つのテーブルを一緒に結合することを考えることができます.
どのようなアプリケーションコードを必要とせずに関連する投稿とコメントを返すクエリを作成できますか?

最近、Postgres JSON機能のAwesomenesを発見!json関数を用いることで,このタスクを容易に実現できる.私たちはあなたがMongoDBを使用しているように感じるようになるクエリを作成することができます.
アクションでそれを見ましょう!
select id, title, (
    select coalesce(jsonb_agg(res), '[]'::jsonb) 
        from (select id, content from comment 
            where comment."postId" = post.id 
            order by "createdAt" desc limit 3) as res
) as comments
from post
order by "createdAt" desc
limit 10;
呼吸、リラックス、それをシンクする瞬間を取るし、ここで何をやったかを見てみましょう.
私はあなたが基本的なSQL理解を持っていると仮定します.複雑な部分に飛び込みましょう.
(
    select coalesce(jsonb_agg(res), '[]'::jsonb) 
        from (select id, content from comment 
            where comment."postId" = post.id 
            order by "createdAt" desc limit 3) as res
) as comments
ここではサブクエリ内のサブクエリを作成します.内部の選択は、メインクエリ内のすべてのポストについて最新の3コメントを格納する結果セットを作成します.
select id, content from comment 
            where comment."postId" = post.id 
            order by "createdAt" desc limit 3
これはPOSTテーブルを参照するWHERE句を追加することで実現されます.これまでのところ、基本的なサブクエリのもの.
今ここでクールな部分ですjsonb_agg . jsonb_agg は集約関数ですcount . aggregate関数は、n行の結果セットを単一の値にします.我々の場合はjsonb_agg N行を本当のJSON配列に変えます!Bjsonb バイナリを表します.レスポンスサイズを最適化するために、結果をバイナリデータとしてエンコードします.データベースドライバは通常のJSONオブジェクトにそれをデコードするのを知っています.
使用jsonb_agg , 最新の3コメントを含むすべてのポストに対して動的にJSON配列を作成します.
最後の部分はcoalesce , これにより、投稿に全くコメントがない場合、空の配列が返されます.
上記のような複雑なクエリを返すクエリを作成する必要があるときはいつでも、私は常にサブクエリとブリリアントjsonb_agg . これは、GraphSQLサーバーを構築するときに非常に一般的です.これは、N + 1問題を解決するのに最適な方法です.
あなたはこれまで生き延びました、そして、私はあなたを誇りに思います!私はあなたの次のSQLクエリの機能の新しいセットを解除したい.
daily.dev すべての新しいタブを最高のプログラミングニュースを提供します.私たちはあなたのための資格のソースの数百人は、将来をハックできるようにランク付けされます.