我在付款表中有多个成员,需要计算最近的失败付款,其中:
1 =成功,2 =失败
必须基于最近的付款,而不是总数! 因此,如果最近的付款成功,那么一个人可能会有失败但是数量会为零。
CREATE TABLE Payment
(`pID` int, `memID` int, `pStatus` int, )
;
INSERT INTO Payment
(`pID`, `memID`, `pStatus)
VALUES
(1, 1, 1001),
(2, 1, 1001),
(3, 1, 1001),
(4, 2, 1001),
(5, 2, 1001),
(6, 1, 1002),
(7, 2, 1002),
(8, 2, 1002),
(9, 1, 1002),
(10, 1, 1002),
(11, 2, 1003),
(12, 1, 1003),
(13, 2, 1003),
(14, 1, 1003),
(15, 2, 1003),
(16, 2, 1004),
(17, 2, 1004),
(18, 2, 1004),
(19, 2, 1004),
(20, 2, 1004);
Retun应该是:
memId | failCount
1001 | 2
1002 | 0
1003 | 1
1004 | 5
答案 0 :(得分:0)
嗯。我们可以获得最后一次未失败的付款的最大ID,然后将更大的ID与失败的付款相加。这基本上可以满足您的需求:
select p.memid, count(*)
from payment p
where id > coalesce((select max(id) from payment p2 where p2.memid = p.memid and p2.pstatus = 1), 0)
group by p.memid;
但是,它并没有返回0,所以让我们把它变成一个条件聚合:
select p.memid,
sum(id > coalesce((select max(id) from payment p2 where p2.memid = p.memid and p2.pstatus = 1), 0)
) as numfails
from payment p
group by p.memid;
Here是一个SQL小提琴。
答案 1 :(得分:0)
有几种方法可以获得该结果。以下是其中一种方法的示例,可能不是最有效的方法,但很容易弄清楚它在做什么:
SELECT n.memID
, COUNT(r.pStatus) AS failCount
FROM ( SELECT m.memID
FROM Payment m
GROUP BY m.memID
) n
LEFT
JOIN Payment r
ON r.memID = n.memID
AND r.pStatus = 2
AND NOT EXISTS ( SELECT 1
FROM Payment p
WHERE p.memID = r.memID
AND p.pStatus = 1
AND p.pID > r.pID
)
GROUP BY n.memID
内嵌视图n
会从付款表中获取所有memID
的列表;我们可以使用其他一些来源,例如memID
是主键的表格,但我们没有提供任何相关信息,因此我们会从付款表中生成一个不同的列表。
接下来,我们对Payment表中的行执行外连接,状态为" failed"。 "技巧"我们使用的是一个NOT EXISTS谓词,用于测试是否或者注意到最近的一行,其中状态为"成功"。如果没有更新的成功,我们只返回一行。行。
然后,我们执行GROUP BY操作来聚合行,因此我们为每个memID获得一行。我们通过对来自r
的列进行COUNT()汇总来计算失败的付款次数。如果我们找到匹配项,我们知道这些汇总非空。
这不是获得结果的唯一方法,还有其他几种方法。