如何在日期过长时选择数字下降的行

时间:2015-09-04 03:23:22

标签: sql sql-server

如果我在维修店有一个程序,并且我想在我的RepairOrder表中选择所有后续维修订单的里程数小于之前维修订单的里程数的车辆,我该如何建立该选择声明?

ID  VehicleID  Mileage  RepairDate
01  1          18425    2013-08-13
02  1          28952    2013-02-26
03  2          22318    2012-08-27
04  3          21309    2012-08-07
05  3          16311    2012-02-27
06  3          16310    2012-02-11
07  4          11098    2011-03-23
08  5          21309    2012-08-07
09  5          16309    2012-02-27
10  5          16310    2012-02-11

在这种情况下,我应该只选择VehicleID 1,因为它的RepairDate大于前一行,但是里程小于前一行。也可能有3排同一车辆,中间日期的里程为3或5000000,我也需要选择那些车辆ID。

使用LEAD()函数的结果

ID  RepairDate  Mileage
25  2011-12-23  45934
48  2009-02-26  13
48  2009-04-24  10
71  2011-07-26  31163
71  2015-01-13  65656

5 个答案:

答案 0 :(得分:2)

对于sql 2014 +

,这是一个使用LEAD()函数的好地方

SQL FIDDLE DEMO

2B992DDFA232h

我的解决方案显示所有列,以便您可以检查哪一行有问题。

我也避免使用WITH NextM as ( SELECT * , LEAD(Mileage, 1, null) over (partition by VehicleID order by RepairDate) NextMileage FROM RepairOrder ) SELECT * FROM NextM WHERE Mileage > NextMileage ,因为OP表明同一辆车可能存在多个错误,这样你就可以看到它。 enter image description here

答案 1 :(得分:0)

它不是非常有效,但你可以做成对选择

select t1.VehicleID 
from table t1, table t2 
where t1.VehicleId = t2.VehicleId 
AND t1.Mileage > t2.Mileage 
AND t1.RepairDate < t2.RepairDate

可能有更好的解决方案,因为成对选择变得极其缓慢,但这应该按原样运行。

答案 2 :(得分:0)

select distinct RO.VehicleID 
from RepairOrder RO 
where exists(select * 
             from RepairOrder 
             where ID != RO.ID 
             and VehicleID = RO.VehicleID and RepairDate > RO.RepairDate 
             and Mileage < RO.Mileage);

答案 3 :(得分:0)

WITH RepairSeqs AS(
    SELECT
        DateSeq = Row_Number OVER (PARTITION BY VehicleID ORDER BY RepairDate),
        MileageSeq = Row_Number OVER (PARTITION BY VehicleID ORDER BY Mileage),
        *
    FROM
       dbo.RepairOrder
)
SELECT *
FROM RepairSeqs
WHERE DateSeq <> MileageSeq;

答案 4 :(得分:0)

select distinct t.VehicleId
from (
select t.*, LEAD(Mileage) OVER (Partition by VehicleId ORDER BY RepairDate) LeadMileageValue
from RepairOrder t
) t
where t.Mileage > t.LeadMileageValue