如何在 mySQL 中从聚合中排除成对的行?
Posted
技术标签:
【中文标题】如何在 mySQL 中从聚合中排除成对的行?【英文标题】:How do I exclude pairs of rows from being aggregated in mySQL? 【发布时间】:2017-03-30 15:07:51 【问题描述】:我们对操作进行了审计跟踪,并要求我报告这些操作所花费的平均时间。
不幸的是,审计跟踪包含“取消”条目,实质上排除了先前的操作。
所以,一些数据。
AuditTrail
ID OrderID ActionQty ActionDate
1 1 1 2002-02-02
2 2 1 2002-02-02
3 1 -1 2003-03-03
4 1 1 2004-04-04
和
Orders
OrderID OrderDate
1 2001-01-01
2 2002-02-02
比较的基准日期是不同的 ActionDate。
这是所需的平均值。
在上面的示例中,需要排除 AuditTrail 条目 1 和 3,因为条目 3 是“取消”,因此需要排除先前的非取消条目(条目 1)。 ID 是连续的,但对于一个订单不一定是连续的,因为有许多订单和许多审计跟踪条目。
更复杂的是,我们可以看到“取消”的运行,这需要进一步回滚。
例如
AuditTrail
ID OrderID ActionQty ActionDate
1030 99 1 2002-02-02
1031 99 1 2002-02-02
1032 99 -1 2003-03-03
1033 99 -1 2004-04-04
在这个例子中,2进2出。
所以。
平均值是总数除以计数。我们可以轻松地使用 SUM(ActionQty)
(GROUP'd BY AuditTrail.OrderID) 来获得正确的订单计数。
获取 AuditEntry 的天数也很容易 (TIMESTAMPDIFF(DAY, Orders.OrderDate, AuditTrail.ActionDate)
)。
但排除正确的...我无法解决。
有什么线索吗?
【问题讨论】:
那么在最后一个例子中,The number of days for an audit entry
在订单 99 上的结果是什么?会不会是0
,因为实际上所有审计行都被取消了?我想,另一种提问方式是:“根据您的示例数据,您想要的结果是什么?”
是的。我确实错过了预期/期望的结果。 OrderID 1 将是 3y3m3d(以天为单位)。 OrderID 2 为 0 OrderID 99 为 0
【参考方案1】:
您可以使用行号方法进行匹配。 给定
MariaDB [sandbox]> select * from t;
+------+---------+-----------+------------+
| ID | OrderID | ActionQty | ActionDate |
+------+---------+-----------+------------+
| 1 | 1 | 1 | 2002-02-02 |
| 2 | 2 | 1 | 2002-02-02 |
| 3 | 1 | -1 | 2003-03-03 |
| 4 | 1 | 1 | 2004-04-04 |
| 1030 | 99 | 1 | 2002-02-02 |
| 1031 | 99 | 1 | 2002-02-02 |
| 1032 | 99 | -1 | 2003-03-03 |
| 1033 | 99 | -1 | 2004-04-04 |
+------+---------+-----------+------------+
8 rows in set (0.00 sec)
这个查询
Select s.id,s.orderid,s.actionqty,s.actiondate
from
(
select t.*,
if(t.orderid<>@p ,@rn:=1,@rn:=@rn+1) rn,
@p:=t.orderid p
from t,(select @block:=0,@rn:=0,@p:=0) rn
where actionqty > 0
order by orderid,id
)s
left join
(
select t.*,
if(t.orderid<>@p ,@rn:=1,@rn:=@rn+1) rn,
@p:=t.orderid p
from t,(select @block:=0,@rn:=0,@p:=0) rn
where actionqty < 0
order by orderid,id
) cans on s.orderid = cans.orderid and s.rn = cans.rn
where cans.id is null
结果
+------+---------+-----------+------------+
| id | orderid | actionqty | actiondate |
+------+---------+-----------+------------+
| 4 | 1 | 1 | 2004-04-04 |
| 2 | 2 | 1 | 2002-02-02 |
+------+---------+-----------+------------+
2 rows in set (0.00 sec)
【讨论】:
在mysql上,所以没有无法重用表t
。 :-/
尝试用你的表名替换 t
@RichardAQuadling - 为什么?是临时表吗?因为这是您无法在查询中访问表两次的主要原因。以上是关于如何在 mySQL 中从聚合中排除成对的行?的主要内容,如果未能解决你的问题,请参考以下文章
如何在一个请求中从 Binance API 获取所有(或多个)对的历史 klines?