我的存储过程有4个参数:startdate,enddate,allocationID&语言。对我的问题真正重要的是日期。
使用这些参数,存储过程将从不同的表中收集汽车日期并返回包含每个月的空记录的选择,并且每月每辆汽车的填充记录在汽车具有有效里程值的情况下。因此,如果日期是'2008-01-01'和' 2008-06-01'这是一个示例结果。
在示例中,第一辆车具有所有月份的值,但第二辆车在第一个月缺失。我现在需要做的是添加逻辑,以便选择中的每辆车每个月都有一行。然后我必须通过获取前一个和下一个里程值来计算该月的里程值。
我知道如何在C#中执行此操作,但我不熟悉SQL。我的问题是如何迭代几个月,然后再次通过carID迭代并检查它们是否有里程值。
我知道我必须制作一个临时表,但我不知道如何只用一段时间和一个案例来做这件事。
--DECLARATION VARS
DECLARE @Taal varchar(5) = 'en-us'
DECLARE @VanDate datetime = '2008-01-01'
DECLARE @TotDate datetime = '2008-06-01'
DECLARE @AllocationID AS uniqueidentifier = 'BD83AEDE-6DFB-4DF5-9F18-C373D6A468D1'
DECLARE @TaalID int
DECLARE @Months int
DECLARE @FirstDay AS DateTime
DECLARE @LastDay AS Datetime
DECLARE @DefaultFirstDay as Datetime
DECLARE @DefaultLastDay as Datetime
DECLARE @ControlDay AS datetime
--DEFAULT MONTHS SPAN
SET @Months = 18
SELECT @TaalID = MIN(eMK_Languages.ID)
FROM eMK_Languages WHERE LEFT(eMK_Languages.LangCode,2) = LEFT (@Taal,2)
Set @Lastday = ISNULL(@TotDate,dateadd(dd,0,datediff(dd,0,{fn NOW()})));
--select @Lastday as Lastday;
Set @Firstday = ISNULL(@VanDate,
DATEADD(dd,-(DAY(DATEADD(mm, -(1-@Months) , @LastDay))-1),DATEADD(mm, 1 -(@Months) , @LastDay)));
--select @Firstday as Firstday;
SET @ControlDay = dateadd(dd,0, datediff(dd,0,@LastDay));
;WITH
MonthList (MonthDate) AS -- lijst van maanden
(
SELECT
DATEADD(dd,-(DAY(DATEADD(mm, 0 , @LastDay))-1),DATEADD(mm, 0 , @LastDay))
UNION ALL
SELECT DATEADD(mm, -1, MonthDate)
FROM MonthList
WHERE (MonthDate > @FirstDay)
),
AllocationList AS
(
SELECT COST.CostAllocationID,
COST.Name as AllocationName
FROM eMK_CostAllocation AS COST
WHERE (COST.CostAllocationID = @AllocationID OR @AllocationID IS NULL)
AND (COST.StartDate <= @LastDay OR COST.StartDate IS NULL)
AND (COST.EndDate IS NULL OR COST.EndDate >= @FirstDay)
UNION ALL
SELECT NULL,NULL
)
,
AllocationCrossList AS
(
SELECT ML.MonthDate,
DATEADD(dd,-1,DATEADD(mm,1,ML.MonthDate)) as endmonth,
ML.MonthDate as X_AXIS,
DATEADD(dd,-1,DATEADD(mm,1,ML.MonthDate)) X_AXIS_2,
AL.CostAllocationID,
AL.AllocationName
FROM MonthList AS ML
CROSS JOIN AllocationList AS AL
)
,CarList AS
(
SELECT
M.MonthDate as beginmonth
, DATEADD(dd,-1,DATEADD(mm,1,M.MonthDate)) as endmonth
, M.MonthDate as X_AXIS
, DATEADD(dd,-1,DATEADD(mm,1,M.MonthDate)) X_AXIS_2
, C.CarID
--, (dbo.fGetAllocationNameFromDate(C.CarID,DATEADD(dd,-1,DATEADD(mm,1,M.MonthDate)))) as AllocationName
, dbo.fGetAllocationFromDate(C.CarID,DATEADD(dd,-1,DATEADD(mm,1,M.MonthDate))) as AllocationID
, C.StartDate
, C.FinalEndDate
, dbo.fGetTranslation(C.CarTypeID,@TaalID) as Nature
, C.BuiltYear
, VHC.Co2Emission
FROM
eMK_Car C
CROSS JOIN MonthList M
CROSS JOIN eMK_Vehicle VHC
WHERE
(
C.StartDate <= DATEADD(dd,-1,DATEADD(mm,1,M.MonthDate))
AND (C.FinalEndDate IS NULL OR C.FinalEndDate >= M.MonthDate )
AND C.VehicleID = VHC.VehicleID
)
)
, unionlist as (SELECT
'Fuelcard' as oorsprong
, CAR.beginmonth
, CAR.endmonth
, CAR.X_AXIS
, CAR.CarID
, CAR.AllocationID
, (CASE WHEN CAR.CarID IS NULL
THEN 'N'
ELSE 'Y'
END ) as ValidData
, CAR.Co2Emission
, fuelcardrefill.Kilometer as kilometerstand
, fuelcardrefill.FK_FuelType
, fuelcardrefill.Date as datum
From CarList AS CAR inner join
dbo.eMK_CarFuelCard as carfuelcard On CAR.CarID = carfuelcard.CarID inner join
dbo.eMK_FuelCard as fuelcard on carfuelcard.FuelCardID = fuelcard.ID inner join
dbo.eMK_FuelCard_Refill as fuelcardrefill on fuelcard.ID = fuelcardrefill.FK_FuelCard
Where
(fuelcardrefill.Date >= CAR.beginmonth and fuelcardrefill.Date <= CAR.endmonth)
UNION
SELECT
'Costs' as oorsprong
, CAR.beginmonth
, CAR.endmonth
, CAR.X_AXIS
, CAR.CarID
, CAR.AllocationID
, (CASE WHEN CAR.CarID IS NULL
THEN 'N'
ELSE 'Y'
END ) as ValidData
, CAR.Co2Emission
, COSTS.Mileage as kilometerstand
, NULL
, COSTS.DateInvoice as datum
FROM
CarList AS CAR inner join
dbo.Emk_Cost as COSTS on CAR.CarID = COSTS.CarID
Where
(COSTS.CostDate > beginmonth and COSTS.CostDate < endmonth)
UNION
SELECT
'Caruse_start' as oorsprong
, CAR.beginmonth
, CAR.endmonth
, CAR.X_AXIS
, CAR.CarID
, CAR.AllocationID
, (CASE WHEN CAR.CarID IS NULL
THEN 'N'
ELSE 'Y'
END ) as ValidData
, CAR.Co2Emission
, CARUSE.MileageStart as kilometerstand
, NULL
, CARUSE.StartDate as datum
FROM
CarList AS CAR inner join
dbo.eMK_CarUse as CARUSE on CARUSE.CarID = CAR.CarID
Where
(CARUSE.StartDate >= beginmonth and CARUSE.StartDate <= endmonth)
UNION
SELECT
'Caruse_end' as oorsprong
, CAR.beginmonth
, CAR.endmonth
, CAR.X_AXIS
, CAR.CarID
, CAR.AllocationID
, (CASE WHEN CAR.CarID IS NULL
THEN 'N'
ELSE 'Y'
END ) as ValidData
, CAR.Co2Emission
, CARUSE.MileageEnd as kilometerstand
, NULL
, CARUSE.EndDate as datum
FROM
CarList AS CAR inner join
dbo.eMK_CarUse as CARUSE on CARUSE.CarID = CAR.CarID
Where
(CARUSE.EndDate >= beginmonth and CARUSE.EndDate <= endmonth)
UNION
SELECT
'AllocationCross' as oorsprong
, AL.MonthDate as beginmonth
, AL.endmonth
, AL.X_AXIS
, NULL as CarID
, AL.CostAllocationID
, 'N' as ValidData
, NULL
, NULL
, NULL
, NULL
From AllocationCrossList as AL)
, resultunionlist as (
SELECT
UL1.*,
CASE WHEN EXISTS(
SELECT *
FROM unionlist AS UL2
WHERE
UL2.CarID = UL1.CarID AND
UL2.datum < UL1.datum AND
UL2.kilometerstand < UL1.kilometerstand OR
UL1.oorsprong = 'Caruse_start'
)
THEN 'Y'
ELSE 'N'
END AS validkmstand
FROM unionlist as UL1)
, totalmileagelist as (
SELECT
'Fuelcard' as oorsprong
, CAR.CarID
, (CASE WHEN CAR.CarID IS NULL
THEN 'N'
ELSE 'Y'
END ) as ValidData
, CAR.Co2Emission
, fuelcardrefill.Kilometer as kilometerstand
, fuelcardrefill.FK_FuelType
, fuelcardrefill.Date as datum
From CarList AS CAR inner join
dbo.eMK_CarFuelCard as carfuelcard On CAR.CarID = carfuelcard.CarID inner join
dbo.eMK_FuelCard as fuelcard on carfuelcard.FuelCardID = fuelcard.ID inner join
dbo.eMK_FuelCard_Refill as fuelcardrefill on fuelcard.ID = fuelcardrefill.FK_FuelCard
Where
(fuelcardrefill.Date < @VanDate )
UNION
SELECT
'Caruse_start' as oorsprong
, CAR.CarID
, (CASE WHEN CAR.CarID IS NULL
THEN 'N'
ELSE 'Y'
END ) as ValidData
, CAR.Co2Emission
, CARUSE.MileageStart as kilometerstand
, NULL
, CARUSE.StartDate as datum
FROM
CarList AS CAR inner join
dbo.eMK_CarUse as CARUSE on CARUSE.CarID = CAR.CarID
Where
(CARUSE.StartDate < @VanDate)
)
, resultlist as (
SELECT
CarID
, '01/01/2000' as beginmonth
, NULL as X_AXIS
, MAX(kilometerstand) as Kilometers
, MAX(Co2Emission) as CO2
FROM
totalmileagelist
GROUP BY CarID
UNION
SELECT
CarID
, beginmonth
, X_AXIS
, MAX(kilometerstand) as Kilometers
, MAX(Co2Emission) as CO2
FROM
resultunionlist
GROUP BY CarID, beginmonth, X_AXIS
)
, withoutprevalueslist as (
select ml.*,
(ml.Kilometers - mlprev.Kilometers) as diff
from resultlist ml outer apply
(select top 1 ml2.*
from resultlist ml2
where ml2.CarId = ml.CarId and
ml2.beginmonth < ml.beginmonth
order by ml2.beginmonth desc
) mlprev
)
SELECT *
FROM withoutprevalueslist
WHERE beginmonth >= @VanDate
option (MAXRECURSION 999)