1 対多の SQL リレーションシップで最新のレコードを取得する
1 対多のデータベース関係を操作する場合、各エンティティの最新のレコードを効率的に選択するのが一般的なタスクです。 たとえば、顧客とその最新の購入内容を 1 つのクエリで表示する必要がある場合があります。
最適なアプローチ
堅牢な方法には、JOIN
と LEFT OUTER JOIN
を組み合わせることが含まれます。
<code class="language-sql">SELECT c.*, p1.* FROM customer c JOIN purchase p1 ON (c.id = p1.customer_id) LEFT OUTER JOIN purchase p2 ON (c.id = p2.customer_id AND p1.date < p2.date OR (p1.date = p2.date AND p1.id < p2.id)) WHERE p2.customer_id IS NULL;</code>
このクエリは、p1
を最新の購入として識別します。 LEFT OUTER JOIN
と p2
は、より新しい日付、または日付が等しい場合はより高い ID (より新しいエントリを示す) の購入を検索します。 p2.customer_id
が NULL
である行は、各顧客の最新の購入を表します。
パフォーマンスのためのデータベースのインデックス作成
列 purchase
を使用して (customer_id, date, id)
テーブルに複合インデックスを作成すると、クエリのパフォーマンスが大幅に向上します。このインデックスは、これらの基準に基づいて検索と結合を最適化します。
非正規化に関する考慮事項
複雑なシナリオの場合は、非正規化 (最後の購入の詳細を customer
テーブルに直接追加) が有利な場合があります。これにより、クエリが簡素化され、特定の使用例のパフォーマンスが向上します。 ただし、パフォーマンスの向上と、潜在的なデータ整合性の問題やメンテナンスのオーバーヘッドを慎重に比較検討してください。
連続した ID の簡略化されたクエリ
購入 ID が日付順に並べられることが保証されている場合は、LIMIT
を使用した簡略化されたクエリが可能です。
<code class="language-sql">SELECT c.*, pu.* FROM customer c JOIN purchase pu ON (c.id = pu.customer_id) ORDER BY pu.id DESC LIMIT 1;</code>
このアプローチは、ID が各顧客の購入内で単調なシーケンスとして機能し、最も高い ID に基づいて最新の購入を取得できるという前提に基づいています。 ID シーケンスが厳密に日付順に並べられていない場合、この方法は最初の方法よりも堅牢性が低くなります。
以上が1 対多の SQL リレーションシップで最後のレコードを効率的に取得するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。