治愈我的密度,我认为您的要求是非常合理的,将问题视为“更换燃料成本” - 因此使用下一次加油的燃料成本而不是之前购买实际使用的燃料的成本(这真的很复杂,真的快速地)。然后音量无关紧要。试穿这个尺寸。
SELECT
T.*,
P.*, -- from previous purchase
N.*, -- from next purchase (NULL if none yet)
TripCost = N.Total * T.Miles / M.MilesThisFill
FROM
dbo.Trips T
CROSS APPLY (
SELECT TOP 1 *
FROM dbo.Purchases P
WHERE P.[Date] < T.travelDate
ORDER BY P.[Date] DESC
) P
CROSS APPLY (
SELECT TOP 1 *
FROM dbo.Purchases P
WHERE P.[Date] > T.travelDate
ORDER BY P.[Date]
) N
CROSS APPLY (
SELECT Sum(miles) MilesThisFill
FROM dbo.Trips T2
WHERE
T2.[Date] > P.[Date]
AND T2.[Date] < N.[Date]
) M;
或者这里有一个版本对问题有非常不同的看法,但应该给出相同的结果。让我知道哪个表现更好,好吗?( SET STATISTICS IO ON; SET STATISTICS TIME ON;
)
WITH PSeq AS (
SELECT
Seq = Row_Number() OVER (ORDER BY [Date]),
*
FROM dbo.Purchases
), Slices AS (
SELECT
FromDate = P.[Date],
ToDate = N.[Date],
N.Total
FROM
PSeq P
INNER JOIN PSeq N
ON P.Seq + 1 = N.Seq
), TotalMiles AS (
SELECT
S.FromDate,
Sum(T.Miles) MilesThisFill
FROM
Slices S
INNER JOIN dbo.Trips T
ON T.travelDate BETWEEN S.FromDate AND S.ToDate
GROUP BY
S.FromDate
)
SELECT
T.travelDate,
S.FromDate,
S.ToDate,
TripCost = S.Total * T.Miles / M.MilesThisFill
FROM
Slices S
INNER JOIN dbo.Trips T
ON T.travelDate BETWEEN S.FromDate AND S.ToDate
INNER JOIN dbo.TotalMiles M
ON S.FromDate = L.FromDate;
对于任何拼写错误或错误,我提前道歉......我没有测试过代码。
只是为了笑,这是第一个被变形为可以在 SQL Server 2000 上运行的版本的查询!
SELECT
T.travelDate,
T.Miles,
T.ToDate,
TripCost = P.Total * T.Miles / M.MilesThisFill
FROM
(
SELECT
T.travelDate,
T.Miles,
ToDate = (
SELECT TOP 1 P.Date
FROM dbo.Purchases P
WHERE P.[Date] > T.travelDate
ORDER BY P.[Date]
)
FROM
dbo.Trips T
) T
INNER JOIN (
SELECT
ToDate = (
SELECT TOP 1 P.Date
FROM dbo.Purchases P
WHERE P.[Date] > T2.travelDate
ORDER BY P.[Date]
),
MilesThisFill = Sum(T2.Miles)
FROM dbo.Trips T2
GROUP BY
(
SELECT TOP 1 P.Date
FROM dbo.Purchases P
WHERE P.[Date] > T2.travelDate
ORDER BY P.[Date]
)
) M ON T.ToDate = M.ToDate
INNER JOIN dbo.Purchases P
ON T.ToDate = P.[Date];
这实际上表明我可能不需要在我的第一个查询中查找之前的购买日期,如果我做得对的话......所以这是一个最终版本:
WITH TripData AS (
SELECT
T.Miles,
T.travelDate,
ToDate = (
SELECT TOP 1 P.[Date]
FROM dbo.Purchases P
WHERE P.[Date] > T.travelDate
ORDER BY P.[Date]
)
FROM
dbo.Trips T
)
SELECT
T.*,
P.*,
TripCost = P.Total * T.Miles / M.MilesThisFill
FROM
TripData T
INNER JOIN dbo.Purchases P
ON T.ToDate = P.[Date]
INNER JOIN (
SELECT
T2.ToDate,
Sum(T2.Miles) MilesThisFill
FROM TripData T2
GROUP BY
T2.ToDate
) M ON T.ToDate = M.ToDate;
注意: TripCost 表达式的顺序很重要,因为 Miles 和 TotalMiles 是整数。如果你把 P.Total 放在最后,你会得到错误的答案,因为 Miles / TotalMiles 将被转换为整数。