1

我有一个包含车辆列表的表(车辆)。

VehicleID
PlateNo
CurrentDriver

我还有一个表(历史记录),其中包含车辆的驾驶员历史记录:

HistoryID
VehicleID
ReceivedDate (vehicle receiving date)
DriverName

我有另一个表(维修),其中包含所有车辆的维修:

RepairID
VehicleID
RepairDate
RepairCost

使用 SQL Server 并基于 History 表,我想获取给定 DriverName 的两个日期之间的所有 RepairCost 值。

例如,我想获取司机 'John Doe' 在 01.01.2013 和 01.05.2013 之间的所有 RepairCost 值,他在此期间被分配到三辆不同的车辆。

到目前为止,我的查询是:

SELECT H.DriverName, R.RepairCost, R.RepairDate
  FROM Repairs AS R 
 INNER JOIN Vehicles AS V ON R.VehicleID = V.VehicleID 
 INNER JOIN History H ON H.VehicleID = V.VehicleID 
 WHERE H.DriverName = 'John' 
   AND R.RepairDate BETWEEN '01.01.2013' AND '04.01.2013'

SQL Fiddle中还有一些示例数据。

问题似乎是我两次得到所有结果。

后期编辑:到目前为止我的进展:

DECLARE @Driver varchar(50),@StartDt datetime, @EndDt datetime

SELECT @Driver = 'John Doe',@StartDt = '20130101' ,@EndDt = '20130501'

;With VehicleAllocation
AS
(
SELECT h.*,h1.ChangeDate
FROM History h
OUTER APPLY (SELECT MIN(ReceivedDate) AS ChangeDate
FROM History
WHERE VehicleID = h.VehicleID
AND DriverName <> h.DriverName
AND ReceivedDate > h.ReceivedDate
)h1
WHERE h.DriverName = @Driver
)
SELECT *
FROM VehicleAllocation h
INNER JOIN Repairs r
ON r.VehicleID = h.VehicleID
WHERE DriverName = @Driver
AND RepairDate > = @StartDt
AND RepairDate < @EndDt + 1
AND RepairDate BETWEEN h.ReceivedDate AND COALESCE(h.ChangeDate,RepairDate)

我发现'AND DriverName <> h.DriverName'这一行有问题。为什么这条线有用?如果我在历史表中一个接一个地有相同的司机姓名,它会跳到该司机姓名的最后一个汽车交付日期。

样本数据:

“历史”表

ReceivedDate  DriverName
04.11.2013    Mike
13.11.2013    Dan
15.11.2013    Dan
17.11.2013    Ryan
20.11.2013    Dan
22.11.2013    Ryan
25.11.2013    Mike
26.11.2013    Dan
29.11.2013    Ryan
04.12.2013    Dan

“维修”表

RepairDate RepairCost
05.11.2013 2615.30
14.11.2013 135.66
16.11.2013 4913.04
18.11.2013 538.92
21.11.2013 152.48
23.11.2013 5946.89
26.11.2013 3697.64
27.11.2013 734.01
30.11.2013 279.62

查询结果

RepairDate RepairCost
07.11.2013 380.00
14.11.2013 135.66
16.11.2013 4913.04
16.11.2013 4913.04
21.11.2013 152.48
27.11.2013 734.01

正如您在查询结果中看到的,第 3 行和第 4 行具有相同的值/日期。查询间隔为 01-01-2013 <-> 31-12-2013。

另外,如果我想从不同的表中获取不同列的总和怎么办?例如,'Repairs' 表中的 SUM(Total) 列,'Tires' 表中的 SUM(Value) 列...

如何调整脚本?

谢谢!

4

2 回答 2

2

我不知道您为什么在查询中包含 Vehicle 表,因为您不希望从那里获得任何信息。

您将获得“双倍”结果,因为您将每个维修(例如 1 月 15 日的维修)与具有相同车辆 ID 的每个记录匹配为历史(其中有三个!)。其中两场比赛是驾驶约翰,所以你得到两个结果。

您想要的只是匹配根据您的历史记录表是修复时的驱动​​器的驱动程序!

因此,我首先将每个 repairdate 与历史表中实际匹配的 Receiveddate 进行匹配:

SELECT R1.Repairdate, Max(H1.ReceivedDate) as ReceivedDate
FROM Repairs R1
JOIN History H1 
  ON R1.VehicleID=H1.VehicleID 
 AND H1.ReceivedDate < R1.RepairDate

GROUP BY R1.RepairDate

然后我在连接中使用该查询来接收想要的数据:

SELECT R.RepairDate, H.DriverName, R.RepairCost 
  FROM Repairs AS R 
  JOIN History H ON R.VehicleID=H.VehicleID 
  JOIN (
       SELECT R1.Repairdate, Max(H1.ReceivedDate) as ReceivedDate
         FROM Repairs R1
         JOIN History H1 
           ON R1.VehicleID=H1.VehicleID 
          AND H1.ReceivedDate < R1.RepairDate
        GROUP BY R1.RepairDate) 
        AS H2
    ON R.Repairdate = H2.Repairdate
   AND H.ReceivedDate = H2.Receiveddate
 WHERE R.RepairDate BETWEEN '01.01.2013' AND '04.01.2013' 
   AND H.DriverName = 'John'

这返回了 6 条记录:http ://sqlfiddle.com/#!3/fcebf/62

作为健全性检查,省略完整WHERE的日期和名称,并在选择中包括车辆编号。

您将获得 14 次维修,列出当时驾驶车辆的司机的姓名。您可以根据您的历史数据轻松确认当时与车辆关联的驾驶员是正确的:

DRIVERNAME  VEHICLEID   REPAIRDATE  REPAIRCOST
John    1   January, 15 2013 00:00:00+0000  10
Ryan    2   January, 18 2013 00:00:00+0000  15
Ryan    2   January, 22 2013 00:00:00+0000  15
John    1   February, 03 2013 00:00:00+0000 5
Ryan    2   February, 05 2013 00:00:00+0000 25
John    1   February, 10 2013 00:00:00+0000 10
John    2   February, 26 2013 00:00:00+0000 10
Ryan    1   March, 01 2013 00:00:00+0000    100
John    2   March, 03 2013 00:00:00+0000    30
John    2   March, 08 2013 00:00:00+0000    5
Ryan    1   March, 10 2013 00:00:00+0000    45
Ryan    1   March, 17 2013 00:00:00+0000    25
Ryan    2   March, 25 2013 00:00:00+0000    10
Ryan    2   March, 28 2013 00:00:00+0000    30
于 2013-11-28T08:00:41.920 回答
0

如果您将 HistoryID 添加到查询中,您会注意到行不重复,但它们具有不同的 HistoryID,请尝试此查询

SELECT H.DriverName, R.RepairCost, R.RepairDate , H.HistoryID
FROM
    Repairs AS R
    INNER JOIN Vehicles AS V ON R.VehicleID=V.VehicleID
    INNER JOIN History H ON H.VehicleID=V.VehicleID 
WHERE H.DriverName='John' AND R.RepairDate BETWEEN '01.01.2013' AND '04.01.2013'

所以我认为你的数据有问题。

您可以使用 消除这些重复的行DISTINCT,但我建议您仔细检查历史表数据

于 2013-11-03T13:49:23.957 回答