从查询中删除行

时间:2016-01-12 12:12:21

标签: sql-server

我有下表:

OrderID | OldOrderID    | Action    | EntryDate | Source 
    1   |     NULL      |   Insert  | 2016-01-12|   A
    1   |     NULL      |   Remove  | 2016-01-13|   A
    2   |     NULL      |   Insert  | 2016-01-12|   B
    3   |     NULL      |   Insert  | 2016-01-12|   C
    4   |       3       |   Insert  | 2016-01-13|   C
    4   |     NULL      |   Remove  | 2016-01-14|   C

我想查询当前有效订单的所有订单 - 他们没有删除操作。目前我使用此查询执行此操作:

WITH Active AS 
(
  SELECT *, rn = ROW_NUMBER() 
    OVER (PARTITION BY OrderID,Source ORDER BY EntryDate DESC)
  FROM Orders
)
SELECT *
FROM Active WHERE [Action] <> 'Remove' AND rn = 1;

问题在于某些订单获得子订单(OrderID 3获取子订单ID 4)并且如果孩子获得操作移除查询也应该忽略父查询,但是当前查询它是否有剂量。

简而言之,当前查询得到了我的结果:

OrderID | OldOrderID    | Action    | EntryDate | Source 
    2   |     NULL      |   Insert  | 2016-01-12|   B
    3   |     NULL      |   Insert  | 2016-01-12|   C

但我需要这个结果:

OrderID | OldOrderID    | Action    | EntryDate | Source 
    2   |     NULL      |   Insert  | 2016-01-12|   B

是否可以修复查询以获得这样的结果?

2 个答案:

答案 0 :(得分:0)

试试这个:

;WITH CTE AS (
   SELECT OrderID, OldOrderID, Action, EntryDate, Source,
          COUNT(CASE WHEN Action = 'Remove' THEN 1 END) 
          OVER (PARTITION BY OrderID) AS IsRemoved,
          ROW_NUMBER() OVER (PARTITION BY OrderID ORDER BY EntryDate) AS rn
   FROM Orders  
)
SELECT c1.*
FROM CTE AS c1
LEFT JOIN CTE AS c2 ON c1.OrderID = c2.OldOrderID AND c2.IsRemoved >= 1
WHERE c1.rn = 1 AND c1.IsRemoved = 0 AND c2.IsRemoved IS NULL

上述查询使用COUNT() OVER()来计算每个Action = 'Remove'分区中OrderID的出现次数。因此,IsRemoved的值等于或大于1表示已删除的&#39;订购。

答案 1 :(得分:0)

我还在dba stackexchange上提出了问题并得到了以下answer,这很有效。