I'm trying to bulk-get all of the latest payments for a group of user ids, but I've been struggling with getting all of them under a unified query
I went with:
SELECT t1.*
FROM movements t1 LEFT JOIN movements t2
ON (t1.user = t2.user AND t1.id < t2.id)
WHERE t2.id IS NULL
AND t1.user IN ({$ids}) AND t1.type='payment' AND t1.concept!='4' AND t1.confirmed
...which worked to an extent, but some entries were being left out. I extended it to
ON (t1.user = t2.user AND t1.id < t2.id)
WHERE t2.id IS NULL AND t2.date IS NULL
and that yielded more results, but some of them weren't being selected still.
Here are two samples where the query will not yield anything
id user concept date type confirmed
---------------------------------------------------------------------------------
29755 107 3 2022-06-12 00:01:00 payment 1
31257 107 3 2022-07-12 00:00:00 payment 1
32189 107 3 2022-08-12 00:00:00 payment 1
32460 107 COMISSION BALANCE 2022-08-23 10:50:50 comission
id user concept date type confirmed
---------------------------------------------------------------------------------
27298 8408 3 2022-03-11 08:44:53 40 payment
28446 8408 3 2022-03-11 00:01:00 40 payment 1
28447 8408 3 2022-04-19 17:22:42 40 payment
Using the "crude" alternative does, obviously.
SELECT * FROM movements WHERE user=107 AND (etc) ORDER BY id DESC LIMIT 1
id user concept date type confirmed
---------------------------------------------------------------------------------
32189 107 3 2022-08-12 00:00:00 payment 1
Since I have the ids, I could simply do a foreach
for every $user
and make a million individual calls, but I'd rather avoid that.
I can tell there's something off with the "topmost" rows not meeting the full criteria, but I have no clue on how to tell SQL to get me the ones that do.
How could I achieve this in a clean way?
To select the row with the highest id for each user that matches the additional criteria, even if there's a row with a higher id that doesn't match the additional criteria, you need to add to your on clause:
and t2.type='payment' AND t2.concept!='4' AND t2.confirmed