[英]Reliable way of getting the max value of a column for each unique user id while meeting other criteria
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我正在尝试批量获取一组用户 ID 的所有最新付款,但我一直在努力将所有这些付款置于统一查询下
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.由于我有 ID,我可以简单地为每个$user
做一个foreach
并进行一百万个单独的调用,但我宁愿避免这种情况。
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.我可以说“最上面”的行不符合全部标准,但我不知道如何告诉 SQL 让我得到满足的那些。
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:对于 select 匹配附加条件的每个用户具有最高 id 的行,即使存在与附加条件不匹配的具有更高 id 的行,您需要添加到您的 on 子句:
and t2.type='payment' AND t2.concept!='4' AND t2.confirmed
select id
,user
,concept
,date
,type
,confirmed
from (
select *
,row_number() over(partition by user order by id desc) as rn
from t
where confirmed = 1
) t
where rn = 1
id ID | user用户 | concept概念 | date日期 | type类型 | confirmed确认的 |
---|---|---|---|---|---|
32189 32189 | 107 107 | 3 3 | 2022-08-12 00:00:00 2022-08-12 00:00:00 | payment支付 | 1 1 |
28446 28446 | 8408 8408 | 3 3 | 2022-03-11 00:01:00 40 2022-03-11 00:01:00 40 | payment支付 | 1 1 |
You may also try the following:您还可以尝试以下方法:
Select T.id, T.user, T.concept, T.date, T.type, T.confirmed
From
movements T
Join
(
Select MAX(id) lastid, user
From movements
Where user IN (107, 8408) And type='payment' And concept!='4' And confirmed
Group By user
) D
On T.id = D.lastid
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.