我们假设我有下表名为订单:
---------------------------------
| OrderId | Status | CustomerId |
---------------------------------
| 1 | + | 2 |
---------------------------------
| 2 | - | 1 |
---------------------------------
| 3 | + | 2 |
---------------------------------
| 4 | + | 1 |
---------------------------------
| 5 | - | 3 |
---------------------------------
| 6 | + | 4 |
---------------------------------
| 7 | + | 3 |
---------------------------------
问题是如何在每个客户取消一个订单后删除下一个订单?我基本上想删除id = 4,7的订单。 所以结果应该是:
---------------------------------
| OrderId | Status | CustomerId |
---------------------------------
| 1 | + | 2 |
---------------------------------
| 2 | - | 1 |
---------------------------------
| 3 | + | 2 |
---------------------------------
| 5 | - | 3 |
---------------------------------
| 6 | + | 4 |
---------------------------------
我使用SQL Server,但我真的很好奇使用ANSI SQL编写它。
答案 0 :(得分:1)
您可以获得每位客户的最后取消订单。然后删除订单:
with todelete as (
select t.*,
min(case when status = '-' then orderid end) over
(partition by customerid) as deleted_orderid
from table t
)
delete from todelete
where orderid > deleted_orderid;
编辑:
要仅删除下一个,请使用row_number()
:
with todelete as (
select t.*, min(case when orderid > deleted_orderid then orderid end) over
(partition by customerid) as orderid_to_delete
from (select t.*,
min(case when status = '-' then orderid end) over
(partition by customerid) as deleted_orderid
from table t
) t
)
delete from todelete
where orderid = orderid_to_delete;
编辑II:
如果要在任何删除后删除下一个订单,查询会更简单:
with todelete as (
select t.*, lag(status) over (partition by customerid order by orderid) as prev_status
from table t
)
delete from todelete
where prev_status = '-';
这是ANSI SQL。如果您使用的是SQL Server 2008,则需要使用相关的子查询或cross apply
(我并非100%确定cross apply
将在删除CTE中起作用,但它应该。)