迭代SQL查询?

时间:2013-11-27 13:29:40

标签: sql oracle

我的Oracle DB中的情况非常困难。我有一个表设置如下:

ID              File_route_group   CollectID      DeliveryID      Sequence
----------      ------------       ---------      ------------    --------
11483              12                 123            411             1
12174              12                 411            523             2
12465              12                 523            611             3
12165              46                 215            662             1
52462              12                 266            394             4
12199              46                 662            718             2
61244              12                 394            980             5

每一行代表某个文件所采用的“路由”,而后一行(下一个序列)应始终与前一个序列DeliveryID具有相同的CollectID。

在此示例中,行ID 52462错误。它应该具有collectID 611(因为序列3的行将其作为其deliveryID)。

有没有办法创建一个返回此行的查询(ID为52462)?如下:

ID              File_route_group   CollectID      DeliveryID      Sequence
----------      ------------       ---------      ------------    --------
52462              12                 266            394             4

3 个答案:

答案 0 :(得分:3)

WITH cte AS
( SELECT ID,
         File_route_group,
         CollectID, 
         DeliveryID,
         Sequence,
         LAG(DeliveryID, 1) OVER (PARTITION BY File_route_group 
                                     ORDER BY Sequence)
             Previous_DeliveryID
  FROM Routes
)
SELECT *
FROM cte 
WHERE ( CollectID <> Previous_DeliveryID
     OR CollectID IS NULL
     OR Previous_DeliveryID IS NULL
      )
  AND Sequence > 1 ;

SQL-Fiddle

进行测试

答案 1 :(得分:1)

您可以将表格与自身联系起来,以表示“当前”和“上一个”条目之间的关系:

SELECT * FROM route current_route
JOIN route last_route 
  ON current_route.Sequence = last_route.Sequence + 1
  AND current_route.File_route_grp = last_route.File_route_grp
WHERE current_route.CollectID <> last_route.DeliveryID

请注意,虽然在其他答案中提出的LAG()的使用是在Oracle中执行此操作的更优雅且可能更高效的方式,但是此解决方案更具可移植性并且也可以工作,例如:使用MySQL和其他DBMS。

答案 2 :(得分:0)

在派生表格中使用LAG函数获取PreviousDeliveryID,然后过滤CollectionId不等于PreviousDeliveryID

的位置
SELECT ID, Customer_id, CollectID, DeliveryID, Sequence
FROM (
    SELECT ID, Customer_id, CollectID, DeliveryID, Sequence, LAG(DeliveryID, 1) OVER(ORDER BY ID) AS PrevDeliveryID
    FROM Routes
) AS t
WHERE t.CollectionID <> t.PrevDeliveryID