我有一个包含两个表的数据库:users
和payment
s
每个用户都有很多付款,每笔付款都可以成功或失败。
我需要编写一个查询来获取最后4笔付款失败的所有用户。
这是我到目前为止所尝试的:
select *
from users u
where u.id in(
select p.user_id
from payments
where p.status = 'failed'
group by p.user_id
having count(p.id) = 4
);
但正如您所看到的,这不仅仅是检查最后4笔付款,还包括所有付款。因此,它将返回4次付款失败的用户(在全球范围内,而不仅仅是最后4次)。
我不知道它是否重要,但表格上的字段是:
用户:
id | name | email | password
付款:
id | date | status | user_id
| | (can be success or failed) | (FK)
这sqlfiddle将有助于了解我的需求。
该查询返回所有4次付款失败的用户。但我只需要最近4次付款失败的用户。在这种情况下,它将只是id为5的用户
答案 0 :(得分:1)
如果您想要最近4次交易失败的用户(只有最后4次,而不是4次),那么以下查询应该完成工作:
select u.* from users u
where
id in
(select p.user_id from payment p
where (select count(*) from payment p1
where p.user_id = p1.user_id
and p.date <= p1.date
order by p1.user_id asc,p1.date desc
) <= 4
and p.status <> 'success'
group by p.user_id
having count(*)>=4);
希望它有所帮助!
答案 1 :(得分:1)
这有效
SELECT x.user_id, count(*) as cnt
FROM (
SELECT a.user_id, a.date, a.status FROM payment AS a WHERE
(SELECT COUNT(*) FROM payment AS b
WHERE b.user_id = a.user_id AND b.date >= a.date) <= 4
ORDER BY a.user_id ASC, a.date DESC) AS x
WHERE x.status = 'failed'
GROUP BY x.user_id
HAVING cnt >=4;
答案 2 :(得分:0)
您想使用LIMIT关键字,并指定ORDER。
试试这个
select *
from users u
where u.id in(
select p.user_id
from payments
where p.status = 'failed'
group by p.user_id
having count(p.id) = 4
) ORDER BY p.id DESC LIMIT 4;
不完全确定您在WHERE语句中尝试执行的操作,但ORDER BY p.id DESC LIMIT 4
将检索最近的四行。
答案 3 :(得分:0)
我认为你可以使用这样的查询:
select users.id, users.name, users.email, users.password
from users
left join (
select p1.id, p1.date, p1.status, p1.user_id,
count(p2.id) seq -- this count() creates a sequence number for each user ordered by date
from payment p1
left join payment p2
on p1.user_id = p2.user_id -- here I set sequence for each user
and p1.date <= p2.date -- here I set sequence is ordered by data
group by p1.id, p1.date, p1.status, p1.user_id
) t
on users.id = t.user_id
where t.seq < 5 -- Now filter last 4 sequences of each user's payments
and t.status = 'failed'
group by users.id, users.name, users.email, users.password
having count(*) = 4; -- At last filter those have 4 failed in last 4 sequences
<强> [ SQL Fiddle Demo ] 强>