Sql 如何选择数字随日期的增加而减少的行
如果我在修理厂有一个程序,并且我想在我的修理单表中选择后一个修理单的里程数小于前一个修理单的里程数的所有汽车,我如何生成select语句Sql 如何选择数字随日期的增加而减少的行,sql,sql-server,Sql,Sql Server,如果我在修理厂有一个程序,并且我想在我的修理单表中选择后一个修理单的里程数小于前一个修理单的里程数的所有汽车,我如何生成select语句 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
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,因为它的维修日期大于前一行,但里程数小于前一行。同样的车辆也可能有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
这不是非常有效,但你可以做两两选择
select t1.VehicleID
from table t1, table t2
where t1.VehicleId = t2.VehicleId
AND t1.Mileage > t2.Mileage
AND t1.RepairDate < t2.RepairDate
可能有更好的解决方案,因为按对选择的速度非常慢,但这应该可以正常工作。这是使用sql 2014函数的好地方+
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);
我的解决方案将显示所有列,以便您可以检查出现问题的行
此外,我也避免使用distinct,因为OP建议同一辆车可能会有几个错误,这样你们就可以看到所有的错误。
我不理解您的3行样品,您能否详细说明或将其作为5号车包含在样品数据中。还有,您正在使用什么rdbms?我正在使用Sql server和SSM,我刚刚为您添加了数据。因此,查询还应选择vehicleID 5,因为中间维修的里程数小于前一行。我也应该说3行或更多行。一辆车可能有10个维修订单,其中一个里程是错误的,我需要标记它。sql server的哪个版本?所以这只是为了检测数据错误。但是你想要vehicleID或发生错误的ID?为什么同一辆车,例如vehicleID 1,有不同的里程数,更奇怪的是,根据维修日期,同一辆车ID 1在以后的维修日期的里程数比以前的维修日期少,我很困惑。嗨,来自委内瑞拉@JuanRuizdeCastilla OP说是标记错误,我猜猜测数据录入。虽然这可能是一个可怕的解决方案,请考虑添加一些澄清为什么这是一个很好的答案,它是什么。2012@mheptinstall你是对的。第一行适用于2014+但下一段适用于:SQL Server SQL Server 2012通过当前版本,这些肯定不是正确的结果。有些vehicleID只出现一次,有些出现两次的其他vehicleID在较大日期的里程数较大,而其他出现两次的vehicleID在较大日期的里程数较小。这是返回的前几个结果。请告诉我您认为错误的具体结果是什么?我添加了一张图片来帮助您描述问题。结果是您的评论是您的愿望输出吗?如果是这样,不要使用评论,只需更新你的问题并在评论中提及即可。你可以在那里做得更好。因为我认为你的规则只会产生两行。我认为如果你展示你的欲望输出并解释原因会更好。
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;
WITH NextM as (
SELECT
* ,
LEAD(Mileage, 1, null) over (partition by VehicleID order by RepairDate) NextMileage
FROM RepairOrder
)
SELECT *
FROM NextM
WHERE Mileage > NextMileage
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