I am trying to get all customers with their latest payment transaction, including customers without any transaction:
SELECT c.customer_id, c.phone_number, c.email
, p.transaction_no, p.amount, p.transaciton_datetime
FROM tbl_customers c
LEFT JOIN (
SELECT customer_id, transaction_no, amount, transaciton_datetime
FROM tbl_payment_transactions
ORDER BY payment_transaction_id DESC
LIMIT 1
) p
ON c.customer_id = p.customer_id
The above query returns NULL for p.transaction_no, p.amount, p.transaciton_datetime
in every row. But I can make sure that there are transactions made by customers in tbl_payment_transactions
.
2
Answers
You want the subquery to be run once per each different row of the driving table
tbl_customers
. This is called a lateral subquery and takes the form:The Impaler provided the correct form with a
LATERAL
subquery.Alternatively, you can use
DISTINCT ON
in a subquery and a plainLEFT JOIN
.Performance of the latter can be better while retrieving all (or most) customers, and if there are only few transactions per customer and/or you don’t have a multicolumn index on
(customer_id, payment_transaction_id)
or(customer_id, payment_transaction_id DESC)
:About performance aspects: