我已经开发了一个查询来处理报告数据。我只需要从所选月份的历史记录表中获得一条记录。
例如:这些是4辆车。车辆“ 1”在以下日期和价格上于2018年11月进行了四次修改:
1). 05 November 2018 with price 1000
2). 15 November 2018 with price 5000
3). 25 November 2018 with price 8000
现在,我想要最后修改日期(11月25日)上的唯一一条记录。
我开发了一个数据库标量函数,并在join子句中使用了该函数,该子句可完美地处理较少的数据。现在,我们有了一些记录(历史记录表中的记录不只是100条),并且该报告存在速度/性能问题。我创建了索引并删除了子查询,但仍然没有太大帮助。
请参阅我尝试过的脚本:
declare @pIntFranchiseId int = 16179;
declare @pDtFrom date = '2018-12-01';
declare @pDtTo date = '2018-12-28';
SELECT ba.[Id],BKAgrHistory.[BookingStart],BKAgrHistory.[BookingEnd],BKAgrHistory.[StartTime],BKAgrHistory.[EndTime]
,ba.[FranchiseId],BKAgrHistory.[FleetId],[BKRenterId],[IsReportGenerated],[StepsCompleted]
,ba.[BookingId],ba.[ReservationId],ba.[RentalAgreementId],[VehicleUsedFor],[OperatorLicence]
,[ClearanceCode],[ExcessAmount],[ClearanceCodeAdditionalDriv],[ExcessAmountAdditionalDriv],[IsClearanceVerified]
,[BKDiscount],BKAgrHistory.[AgreementStatus],[IsTravelingOutsideUk],[OtherCountries],[RentalType],[RenterType],[RenterCompanyType]
,[IsVehicleDelivered],[IsReturnedOnSameAddress],[PickUpAddress],[ReturnAddress],[OtherReturnAddress],[TariffId]
,[SpecialRateId],[IsChargeShortWeekend],[IsChargeLongWeekend],[ChargeHalfDay],[IsDamageProvided],[IsRenterAgreement]
,[BKIsOwnInsurance],[ExpectedMileage],BKAgrHistory.[TotalHireCharge],[BKFreeMiles],[BKExpensePerMile],[BKCollisionDamage],[BKDamage]
,[BKTheft],[BKOverHeight],[BKBookingNotes],[BKFleetCurrentMileage],[BKMileageOut],[BKMileageIn],[BKDamageOut],[BKDamageIn],[Condition]
,[AppliedRates],[Paid],[OnceInvoiced],[InterimInvoiceCount],[PBNumber],[Excess],[StatusId],[CreatedOn],[ModifiedOn],BKAgrHistory.[BookingDays]
,[VATPercentage],[BkOpeningHrsSurcharge],[DrivenMileage],[ParentRAId],[NetTotal],[VatTotal],[GrossTotal],[GrandInsurableRevenue]
,[GrandTotalWithoutExtra],[GrandInsurableRevWithoutExtra],[TariffNetPrice],[OnceMailed],[LastBookingEnd],[LastEndTime],[BkOpeningHrsSurchargeNet]
,[BkOpeningHrsSurchargeVat],BKAgrHistory.[DailyHireCharge],[BkNetExtraDrivenMilesExcess],[BkExtraDrivenMilesExcessVAT],[BkTotalExtraDrivenMilesExcess],[ExcessMilesDays]
,[BkWebWeekendSurcharge],BKAgrHistory.[InsertedUserId],BKAgrHistory.[UpdateUserId],BKAgrHistory.[InsertedDate],BKAgrHistory.[UpdatedDate],BKAgrHistory.[InsertedUserName],BKAgrHistory.[UpdatedUserName],
[SecurityDeposit],[SecurityDepositRuleId]
FROM [dbo].[BookingAgreements] ba
join BookingAgreementAmountHistory BKAgrHistory on BKAgrHistory.Id = dbo.[GetAgreementAmtHistoryId](@pIntFranchiseId,ba.Id,@pDtFrom,@pDtTo)
where
(
DATEADD(day, DATEDIFF(day, 0,BKAgrHistory.BookingStart), 0) <= DATEADD(day, DATEDIFF(day, 0, @pDtFrom), 0) OR
DATEADD(day, DATEDIFF(day, 0,BKAgrHistory.BookingEnd), 0) <= DATEADD(day, DATEDIFF(day, 0, @pDtFrom), 0)
)
and ba.FranchiseId=@pIntFranchiseId and StatusId=1
and ISNULL(BKAgrHistory.AgreementStatus,0) not in (0,2,6,7)
and BKAgrHistory.FleetId in (
select f.Id from Fleets f
join FleetsHistory fleetHis on fleetHis.Id = dbo.[GetVehicleHistoryById](@pIntFranchiseId,BKAgrHistory.FleetId,@pDtFrom,@pDtTo)
where fleetHis.GhostVehicle = 0 and fleetHis.CoreFleet = 1 and isnull(fleetHis.StatusId,0) in (1,4) and
f.Franchise_Id=@pIntFranchiseId and DATEADD(day, DATEDIFF(day, 0, fleetHis.PurchaseDate), 0) <= DATEADD(day, DATEDIFF(day, 0, @pDtTo), 0));
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[GetVehicleHistoryById](@franchiseId int = NULL,@fleetId int = NULL, @fromDate Date = NULL, @toDate Date = NULL)
RETURNS int
AS BEGIN
Declare @returnId int = 0;
Select top 1 @returnId = isnull(Id,0) from FleetsHistory
where TransactionDate =
(Select max(TransactionDate)
from FleetsHistory fh
where fh.Franchise_Id = @franchiseId and fh.Fleet_Id = @fleetId
--group by AgreementId
and (DATEADD(day, DATEDIFF(day, 0, TransactionDate),0)) <= DATEADD(day, DATEDIFF(day, 0, @toDate),0))
order by Id desc;
Return @returnId;
END
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[GetAgreementAmtHistoryId](@franchiseId int = NULL,@agreementId int = NULL, @fromDate Date = NULL, @toDate Date = NULL)
RETURNS int
AS BEGIN
Declare @returnId int = 0;
Select top 1 @returnId = isnull(Id,0) from BookingAgreementAmountHistory
where TransactionDate =
(Select max(TransactionDate)
from BookingAgreementAmountHistory
where FranchiseId = @franchiseId and AgreementId = @agreementId
--group by AgreementId
and (DATEADD(day, DATEDIFF(day, 0, TransactionDate),0)) <= DATEADD(day, DATEDIFF(day, 0, @toDate),0))
order by Id desc;
Return @returnId;
END
答案 0 :(得分:1)
无论其他函数可以做什么,它们都不能提高SQL查询的性能。
我建议将apply
与正确的参数一起使用。鉴于问题中查询的泛滥,样本数据的缺乏和期望的结果以及简单问题与实际查询之间的脱节,很难看到您真正想要的是什么。但想法是:
select ba.*, baah.*
from [dbo].[BookingAgreements] ba outer apply
(select top (1) baah.*
from BookingAgreementAmountHistory baah
where baah.Id = ba.FranchiseId and
baah.AgreementStatus not in (2, 6, 7) and -- this takes care of NULL values
baah.<date> >= @pDtFrom and
baah.<date> <= @pDtTo
order by baah.<date> desc
) baah
where ba.FranchiseId = @pIntFranchiseId;
<date>
是您在问题开头提到的修改日期。目前还不清楚这实际上指的是什么日期。