【发布时间】:2019-06-07 09:34:05
【问题描述】:
我的数据库有两个表:users 和 payments。 users 和 payments 之间存在一对多的关系:每个用户可以有 o 或多个付款,并且付款属于一个用户。此外,每次付款都可能成功或失败。
我需要编写一个查询来获取最近 N 次付款失败的所有用户。
我发现了这个查询,它允许所有支付 N 次或更多(在本例中为 4 次或更多)的用户:
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;
但我不能让它适用于一个确切的数字(在这个例子中,正好是 4)。
表格的结构是:
- 用户:id、姓名、电子邮件、密码、created_at、updated_at
- 付款:id、日期(付款所属的日期)、状态(成功、失败)、user_id、created_at、updated_at
一个例子:
这个sqlfiddle 可能有助于了解我需要什么。它应该只返回用户 4(即最近 4 次付款失败的用户,但也返回用户 5(有 5 次付款失败的用户)。
相同的 DDL:
CREATE TABLE users
(`id` int, `name` varchar(6), `email` varchar(7), `password` varchar(10), `created_at` timestamp, `updated_at` timestamp)
;
INSERT INTO users
(`id`, `name`, `email`, `password`)
VALUES
(1, 'name 1', 'email 1', 'password 1'),
(2, 'name 2', 'email 2', 'password 2'),
(3, 'name 3', 'email 3', 'password 3'),
(4, 'name 4', 'email 4', 'password 4'),
(5, 'name 5', 'email 5', 'password 5')
;
CREATE TABLE payments
(`id` int, `date` varchar(10), `status` varchar(7), `user_id` int ,`created_at` timestamp, `updated_at` timestamp)
;
INSERT INTO payments
(`id`, `date`, `status`, `user_id`)
VALUES
(1, '2019-01-01', 'success', 1),
(2, '2019-01-01', 'failed', 2),
(3, '2019-01-01', 'failed', 3),
(4, '2019-01-01', 'success', 4),
(5, '2019-01-01', 'success', 5),
(6, '2019-01-02', 'success', 1),
(7, '2019-01-02', 'success', 2),
(8, '2019-01-02', 'success', 3),
(9, '2019-01-02', 'success', 4),
(10, '2019-01-02', 'success', 5),
(11, '2019-01-03', 'success', 1),
(12, '2019-01-03', 'failed', 2),
(13, '2019-01-03', 'success', 3),
(14, '2019-01-03', 'failed', 4),
(15, '2019-01-03', 'failed', 5),
(16, '2019-01-04', 'success', 1),
(17, '2019-01-04', 'failed', 2),
(18, '2019-01-04', 'failed', 3),
(19, '2019-01-04', 'failed', 4),
(20, '2019-01-04', 'failed', 5),
(21, '2019-01-05', 'success', 1),
(22, '2019-01-05', 'failed', 2),
(23, '2019-01-05', 'failed', 3),
(24, '2019-01-05', 'failed', 4),
(25, '2019-01-05', 'failed', 5),
(26, '2019-01-06', 'success', 1),
(27, '2019-01-06', 'success', 2),
(28, '2019-01-06', 'failed', 3),
(29, '2019-01-06', 'failed', 4),
(30, '2019-01-06', 'failed', 5),
(31, '2019-01-07', 'failed', 5)
;
【问题讨论】:
-
您想要那些最后一次未失败的用户是 5 次付款之前,和/或那些只有 4 次付款的用户,所有这些都失败了。
-
感谢您的回复@Strawberry。我想要最后 N 次付款(最近 N 次付款)失败的所有用户。因此,在示例中,如果我想要最后 4 次付款失败的用户列表,则唯一满足该要求的用户是用户 4(用户 4 的所有付款:成功、成功、失败、失败、失败、失败。最后 4失败了,所以我希望它在结果集中)