これは、greatest-n-per-group
StackOverflowで定期的に発生する問題の例です。
これが私が通常それを解決することを勧める方法です:
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.id IS NULL;
説明:行p1
が与えられた場合p2
、同じ顧客と後日(または同順位の場合は後日id
)の行があってはなりません。それp1
が本当であるとわかった場合、その顧客の最新の購入です。
インデックスについては、私は複合インデックスを作成したいpurchase
列を超えます(customer_id
、date
、id
)。これにより、カバリングインデックスを使用して外部結合を行うことができます。最適化は実装に依存するため、必ずプラットフォームでテストしてください。RDBMSの機能を使用して、最適化計画を分析します。たとえばEXPLAIN
MySQL。
上に示したソリューションの代わりにサブクエリを使用する人もいますが、私のソリューションを使用すると、関係を簡単に解決できることがわかりました。