从客户订单 table 中查找最新的重复订单 - 慢速交叉应用
Finding the most recent order duplicate from a customer order table - SLOW CROSS APPLY
我只想显示客户订购了完全相同的商品的订单,但只显示之前下的最近完成的订单。
我想获得为同一客户、同一商品下的最直接订单。就像显示重复项一样,但只是最近的。
查询可以很好地完成我想要它做的事情,但是当我将交叉应用添加到我的实际查询时,它会减慢很多速度。
编辑:我也试过 select top 1 而不是使用行号。 rownumber 行使其仅快 1 秒。
declare @orders as table (
ord_id numeric(7,0),
customer_id numeric(4,0),
order_time datetime,
item_id numeric (4,0),
status int NOT NULL
)
insert into @orders values
(1516235,5116,'06/04/2021 11:06:00', 5616, 1),
(1516236,5116,'06/03/2021 13:51:00', 5616, 1),
(1514586,5554,'06/01/2021 08:16:00', 5616, 1),
(1516288,5554,'06/01/2021 15:35:00', 5616, 1),
(1516241,5554,'06/04/2021 11:11:00', 4862, 1),
(1516778,5554,'06/04/2021 11:05:00', 4862, 2)
select distinct *
from @orders o
cross apply (
select a.ord_id, row_number() over (partition by a.customer_id order by a.order_time) as rownum
from @orders a
where a.customer_id = o.customer_id and
a.status != 2 and
a.item_id = o.item_id and
a.order_time < o.order_time
)a
where a.rownum = 1
还有其他方法吗?我怎样才能加快速度?
之前的订单必须有
- 其他订单之前的订单时间
- 相同的客户记录
- 同一条记录
- 之前所有其他记录中的最新记录
- 状态未已取消(1 = 完成;2 = 已取消)
太傻了。这是一个更简单的方法,使用 cross apply
:
select o.*
from @orders o cross apply
(select top (1) a.ord_id
from @orders a
where a.customer_id = o.customer_id and
a.status <> 2 and
a.item_id = o.item_id and
a.order_time < o.order_time
order by a.order_time
) a;
这可以使用 (customer_id, item_id, status, order_time)
上的索引。
注意:如果你想要最近的以前的订单,那么order by
应该使用desc
。但是,这不是代码在问题中的措辞方式。
而且,您应该能够使用 window 功能。如果ord_id
随时间增加:
min(case when status <> 2 then ord_id end) over (partition by customer_id, item_id)
即使这不是真的,也有变化,但由于对状态的过滤,它更复杂(即需要子查询)。
我只想显示客户订购了完全相同的商品的订单,但只显示之前下的最近完成的订单。
我想获得为同一客户、同一商品下的最直接订单。就像显示重复项一样,但只是最近的。
查询可以很好地完成我想要它做的事情,但是当我将交叉应用添加到我的实际查询时,它会减慢很多速度。
编辑:我也试过 select top 1 而不是使用行号。 rownumber 行使其仅快 1 秒。
declare @orders as table (
ord_id numeric(7,0),
customer_id numeric(4,0),
order_time datetime,
item_id numeric (4,0),
status int NOT NULL
)
insert into @orders values
(1516235,5116,'06/04/2021 11:06:00', 5616, 1),
(1516236,5116,'06/03/2021 13:51:00', 5616, 1),
(1514586,5554,'06/01/2021 08:16:00', 5616, 1),
(1516288,5554,'06/01/2021 15:35:00', 5616, 1),
(1516241,5554,'06/04/2021 11:11:00', 4862, 1),
(1516778,5554,'06/04/2021 11:05:00', 4862, 2)
select distinct *
from @orders o
cross apply (
select a.ord_id, row_number() over (partition by a.customer_id order by a.order_time) as rownum
from @orders a
where a.customer_id = o.customer_id and
a.status != 2 and
a.item_id = o.item_id and
a.order_time < o.order_time
)a
where a.rownum = 1
还有其他方法吗?我怎样才能加快速度?
之前的订单必须有
- 其他订单之前的订单时间
- 相同的客户记录
- 同一条记录
- 之前所有其他记录中的最新记录
- 状态未已取消(1 = 完成;2 = 已取消)
太傻了。这是一个更简单的方法,使用 cross apply
:
select o.*
from @orders o cross apply
(select top (1) a.ord_id
from @orders a
where a.customer_id = o.customer_id and
a.status <> 2 and
a.item_id = o.item_id and
a.order_time < o.order_time
order by a.order_time
) a;
这可以使用 (customer_id, item_id, status, order_time)
上的索引。
注意:如果你想要最近的以前的订单,那么order by
应该使用desc
。但是,这不是代码在问题中的措辞方式。
而且,您应该能够使用 window 功能。如果ord_id
随时间增加:
min(case when status <> 2 then ord_id end) over (partition by customer_id, item_id)
即使这不是真的,也有变化,但由于对状态的过滤,它更复杂(即需要子查询)。