MySQL查询获取相关表的最后4条记录

时间:2017-10-03 13:41:23

标签: mysql sql

我有一个包含两个表的数据库:userspayment 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的用户

4 个答案:

答案 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);

检查sqlfiddle

希望它有所帮助!

答案 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 ]