我有用户和他们的付款(确定/失败),需要选择上次付款失败的所有用户(按日期)。玛丽亚布 10+。
这是模式以及我如何尝试解决这个问题,但绝对是错误的:http://sqlfiddle.com/#!9/ 99e867d/6/0
结果应该只有用户 ID 20,因为用户 10 最后一次付款正常。用户 10 的最后一次付款应该从 2020-04-04 开始,而不是像现在这样从 2020-03-03 开始。
感谢您的回答,我写了这样的查询,现在按预期工作:
SELECT t.user_id
FROM (
SELECT p.user_id AS user_id
, p.status AS last_status
, ROW_NUMBER() OVER( PARTITION BY p.user_id ORDER BY p.created DESC ) AS rownum
FROM `payment` AS p
) AS t
WHERE t.rownum = 1
AND t.last_status = 'FAIL';
但是当我将它应用于具有 1m+ 记录的表时,执行时间开始变得糟糕(最多 5-6 秒)。
EXPLAIN EXTENDED
:
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 1206883 100.00 Using where; Using filesort
2 DERIVED p ALL NULL NULL NULL NULL 1206883 100.00 Using where; Using temporary
我已经有了 payment(user_id) 索引,尝试添加索引 payment(user_id,created) 但没有成功——执行计划是一样的。
任何建议如何改进这个?
使用行号
例子
partition by user_id order by created desc
从最近的创建日期开始,为每个 user_id 分配一个递增的数字。在外部查询中过滤,最新日期和状态等于 FAIL
编辑
写法不同