Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL查询以查找最近的记录是否都属于同一类型_Mysql - Fatal编程技术网

Mysql SQL查询以查找最近的记录是否都属于同一类型

Mysql SQL查询以查找最近的记录是否都属于同一类型,mysql,Mysql,我有一个事务表,其模式如下 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 |'decline

我有一个事务表,其模式如下

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越高,事务越近,或者可以假设在列中创建了一个_

在上述情况下,应该返回的唯一订单号是11,因为订单号5有3个拒绝的交易,最近的3个交易是D p D


有没有一种干净的方法可以让纯sql在合理的大约50万行时间内运行。

根本不是一个快速的解决方案,但它应该能满足您的需要我假设最近的事务是id列值较高的事务:


假设id越高,则最近的id越高:

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);
这里有一个方法

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;

表中的记录似乎没有在任何地方记录时间戳。。。您建议如何确定哪些是最新的?…并添加更多样本数据。在开发查询时,您希望确保它涵盖所有情况,对吗?因此,您的示例数据应该至少包含正确查询返回的数据。我编辑了该问题,以便您可以假设有一个created_at列或id列随时间单调增加。这对解决方案应该没有多大区别。这太慢了,我不确定我是否能够验证它是否正确。是的,它可能很慢。对此很抱歉-也不太确定当结果少于3个时该怎么办,但所有结果都已被拒绝。请注意,此解决方案将从order_id上的复合索引中略微受益,响应-但当结果少于3个时,它仍然不知道该怎么办,因为你没有说这很好,并且可以立即运行。唯一的缺点是它不是很灵活,因为如果你想搜索4次拒绝,你必须编写一个新的查询。你是对的。但它可以很容易地扩展:。。。在t3.response=t0.response和t3.order_id=t0.order_id和t3.id=SELECT MAXid FROM transaction,其中idI确认这会给出正确的结果。问题是它有点慢。返回大约50行需要几分钟的时间。作为参考,此查询首先为每个事务分配最近性,然后限制为最近的第三个事务。where子句随后验证所有更新或等于第三个最近交易的交易是否被“拒绝”。这是一个聪明的解决方案,其中3参数是灵活的,并且易于修改。不幸的是,它有点慢,但是一个非常聪明的方法是一种有趣的技术。谢谢你花时间回答,我确实学到了一些东西。
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;
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);