我有一个列表,返回的表格如下所示。我只预览了一辆车,但还有更多。
我现在需要做的是检查当前的KM值是否大于前一个,然后小于下一个。如果不是这种情况,我需要创建一个名为Trustworthy的字段,并且应该用1或0(true / false)填充它。
到目前为止我的结果是:
validKMstand和validkmstand2是我计算它的方式。它没有在一个列表中工作,所以这就是我将它分开的原因。
在我的两次尝试中,我的代码都不起作用。
这是我到目前为止的代码。
FullList as (
SELECT
*
FROM
eMK_Mileage as Mileage
)
, ValidChecked1 as (
SELECT
UL1.*,
CASE WHEN EXISTS(
SELECT TOP(1)UL2.*
FROM FullList AS UL2
WHERE
UL2.FK_CarID = UL1.FK_CarID AND
UL1.KM_Date > UL2.KM_Date AND
UL1.KM > UL2.KM
ORDER BY UL2.KM_Date DESC
)
THEN 1
ELSE 0
END AS validkmstand
FROM FullList as UL1
)
, ValidChecked2 as (
SELECT
List1.*,
(CASE WHEN List1.KM > ulprev.KM
THEN 1
ELSE 0
END
) AS validkmstand2
FROM ValidChecked1 as List1 outer apply
(SELECT TOP(1)UL3.*
FROM ValidChecked1 AS UL3
WHERE
UL3.FK_CarID = List1.FK_CarID AND
UL3.KM_Date <= List1.KM_Date AND
List1.KM > UL3.KM
ORDER BY UL3.KM_Date DESC) ulprev
)
SELECT * FROM ValidChecked2 order by FK_CarID, KM_Date
答案 0 :(得分:3)
也许这样的东西就是你要找的东西?
;with data as
(
select *, rn = row_number() over (partition by fk_carid order by km_date)
from eMK_Mileage
)
select
d.FK_CarID, d.KM, d.KM_Date,
valid =
case
when (d.KM > d_prev.KM /* or d_prev.KM is null */)
and (d.KM < d_next.KM /* or d_next.KM is null */)
then 1 else 0
end
from data d
left join data d_prev on d.FK_CarID = d_prev.FK_CarID and d_prev.rn = d.rn - 1
left join data d_next on d.FK_CarID = d_next.FK_CarID and d_next.rn = d.rn + 1
order by d.FK_CarID, d.KM_Date
使用SQL Server版本2012+,您可以使用lag()
和lead()
分析函数来访问上一行/下一行,但是在版本之前,您可以通过对分区中的行进行编号来完成相同的操作集合。还有其他方法,比如使用相关子查询。
我留下了几个条件,注意到处理每辆车的第一行和最后一行 - 也许那些应该被视为有效的是它们只满足比较的一部分(因为上一行/下一行是空的)?