2015-09-04 20 views
5

如果我在维修店有一个程序,并且想要选择我的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。

使用铅()函数

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 
+0

我不明白你的3排样,你能否详细说明或将其包含在样本数据作为汽车5.还您使用的RDBMS是什么? –

+0

我使用Sms服务器和ssms,我刚刚为你添加了数据。所以查询也应该选择vehicleID 5,因为中间修理的里程比它之前的行少。我也应该说3行或更多行。一辆车可能有10个维修订单,其中1个里程已经搞砸了,我需要举报。 – IQtheMC

+0

什么版本的sql server?所以这只是为了检测数据错误。但是,那么你想要VehiculeID或ID发生错误? –

回答

0

这不是非常有效的,但你可以做一个选择配对

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

有可能是一个更好的解决方案为成对的选择得到结果EXTREMELY SLOW,但这应该按原样工作。

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); 
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; 
2

这是使用LEAD()功能SQL 2014+

SQL FIDDLE DEMO

WITH NextM as (
    SELECT 
     * , 
     LEAD(Mileage, 1, null) over (partition by VehicleID order by RepairDate) NextMileage 
    FROM RepairOrder 
) 
SELECT * 
FROM NextM 
WHERE Mileage > NextMileage 

我的解决方案显示所有列,所以你可以查阅一下行有问题的好地方。

另外我也避免使用distinct,因为OP建议同一辆车可能有几个错误,这样你可以看到这一切。 enter image description here

+0

'LEAD()'也可在2012 – mheptinstall

+0

@mheptinstall你是对的。 [_microsoft page_](https://msdn.microsoft.com/en-us/library/hh213125.aspx)中的第一行说应用于2014+,但接下来的paragrah说'适用于:SQL Server(SQL Server 2012通过当前版本),' –

+0

这些绝对不是正确的结果。有些车辆ID只出现一次,其他VehicleId出现两次在更大的日期里有更大的里程数,其他出现两次的VehicleId在更大的日期里有更小的里程数。这是返回的前几个结果。 – IQtheMC

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 
+0

虽然这可能是一个很好的解决方案,但请考虑增加一些说明,解释为什么这是一个很好的答案以及它的作用。 –

相关问题