我有一个transaction
表格,其格式类似于
id | order_id | response | amount
1 | 2 |'payment' | 1000
2 | 5 |'declined'| 0
3 | 5 |'declined'| 0
4 | 5 |'payment' | 500
5 | 5 |'declined'| 0
6 | 11 |'declined'| 0
7 | 11 |'declined'| 0
9 | 11 |'declined'| 0
我要做的就是查找所有订单,其中该订单的三个最近交易被“拒绝”。假设id越高,事务越新(或者你可以假设有一个created_at列)。
在上述情况下,唯一应返回的order_id为11
,因为虽然order_id 5
有3个已拒绝的交易,但最近的3个交易为D P D
使用在合理的时间内运行的纯sql是否有一种干净的方法(假设约50M行)。
答案 0 :(得分:1)
根本不是一个快速的解决方案,但它应该给你你想要的东西(我假设最近的交易是具有更高id
列的交易):
SELECT * FROM
(
SELECT *,
(
SELECT COUNT(1)
FROM `transaction` a WHERE a.order_id = b.order_id AND
a.id >= b.id
)as num
FROM `transaction`b
) a WHERE num =3
AND NOT EXISTS
(
SELECT NULL FROM `transaction` b where response<>'declined'
and b.order_id = a.order_id and b.id >=a.id
)
答案 1 :(得分:1)
假设越高越近:
SELECT t0.order_id
FROM transaction t0
JOIN transaction t1 ON
((t1.response=t0.response) AND (t1.order_id=t0.order_id) AND
t1.id=(SELECT MAX(id) FROM transaction WHERE id<t0.id and t0.order_id=order_id))
JOIN transaction t2 ON
((t2.response=t0.response) AND (t2.order_id=t0.order_id) AND
t2.id=(SELECT MAX(id) FROM transaction WHERE id<t1.id AND t0.order_id=order_id))
WHERE t0.response='declined' AND
t0.id=(SELECT MAX(id) FROM transaction WHERE order_id=t0.order_id);
答案 2 :(得分:0)
这是一种方式......
SELECT DISTINCT a.order_id
FROM
( SELECT x.*
, COUNT(*) rank
FROM my_table x
JOIN my_table y
ON y.order_id = x.order_id
AND y.id >= x.id
GROUP
BY id HAVING COUNT(*) <= 3
) a
LEFT
JOIN
( SELECT x.*
, COUNT(*) rank
FROM my_table x
JOIN my_table y
ON y.order_id = x.order_id
AND y.id >= x.id
GROUP
BY id HAVING COUNT(*) <= 3
) b
ON b.order_id = a.order_id
AND b.response <> 'declined'
WHERE b.id IS NULL;
小提琴:http://www.sqlfiddle.com/#!2/386aa3/1
只是一个想法......这是否有效(未经测试)......
SELECT DISTINCT x.order_id
FROM my_table x
JOIN my_table y
ON y.order_id = x.order_id
AND y.id >= x.id
GROUP
BY x.id
HAVING COUNT(*) = 3
AND COUNT(*) = SUM(CASE WHEN y.response = 'declined' THEN 1 ELSE 0 END);