Running mysql: 5.7.44
I have a table wInvoices
where I need to update two columns based on the values of the most recent matching record from another table, wPayments
. The wPayments
table holds all CC transactions, success and declined, for each invoice using wInvoices invID
as the binding/matching column. Each invID
could have multiple wPayments
transactions but I only need to get the most current one; and use the values from that match to populate the wInvoices
columns.
invID, paidDate, paidDate, (other columns) = wInvoices
===============================
1001
1002
1003
1004
pid, invID, mDate (other columns) = wPayments
===================================
2000 1001 2020-07-21 09:31:00 **
2001 1001 2020-07-20 08:20:20
2002 1001 2020-07-20 11:30:30
2003 1002 2020-07-20 09:09:00 **
2004 1003 2020-07-20 11:21:00
2005 1002 2020-07-19 13:30:00
2006 1003 2020-07-20 13:58:00 **
2007 1004 2020-07-20 09:45:00
2008 1004 2020-07-20 10:00:00 **
So that the new values of wInvoices
is:
invID, paidDate, paidID, (other columns)
===========================================================
1001 2020-07-21 09:31:00 2000
1002 2020-07-20 09:09:00 2003
1003 2020-07-20 13:58:00 2006
1004 2020-07-20 10:00:00 2008
I have read multiple threads on similar types of updates, but have not been able to find anything that matches my exact requirement. The challenge is accounting for the most recent wPayments record. The closet I can come with is this:
UPDATE wInvoices inv SET
inv.iPaidDate=pay.pDate
inv.iPaidReceipt=pay.pid
FROM (select pid,pDate from wPayments) pay
WHERE where inv.invID=pay.invID ;
…but this does not account for the most recent
wPayments record and could end up populating wInvoice columns with data from older records.
2
Answers
Easiest way to do this IMO is:
But I question your database model; why not just select the newest payment information along with the invoice rather than storing it?
Here’s how I would write the UPDATE:
The join to
pay2
is an alternative to theWHERE NOT EXISTS
solution. If we know thatpay
correlates to any row for the giveninvID
, we don’t want any rowpay2
to exist such that it has the sameinvID
and a greaterpid
. We wantpay
to be only the row with the greatestpid
.So use an outer join, together with a
WHERE
clause to find only the cases where no rowpay2
is found with a greaterpid
. That meanspay
must be the row with the greatestpid
of the set of rows matching the respectiveinvID
.I’m assuming
pid
is unique.