2013-11-03 164 views
1

我有一個表(車輛),其中包含車輛列表。三個表SQL查詢

VehicleID 
PlateNo 
CurrentDriver 

我也有一個表(歷史),它包含了車輛一司機歷史:

HistoryID 
VehicleID 
ReceivedDate (vehicle receiving date) 
DriverName 

我有另一個表(維修),它包含了所有車輛的修理:

RepairID 
VehicleID 
RepairDate 
RepairCost 

使用SQL Server並基於歷史記錄表,我想獲取給定DriverName的兩個日期之間的所有RepairCost值。

例如,我希望在2013年1月1日到2013年5月1日之間獲得司機'John Doe'的所有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) 

我discoverd問題與行 '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行有s ame值/日期。 查詢的時間間隔是01-01-2013 < - > 31-12-2013。

另外,如果我想從不同的表格中獲得不同colums的SUM值? 例如,'Repairs'表中的SUM(Total)列,'Tyres'表中的SUM(Value)列...

如何修改腳本?

謝謝!

+3

您是否可以發佈您的嘗試查詢?你得到什麼錯誤?結果是否與預期不同? – Oded

+0

到目前爲止,我已經使用SQL小提琴向您顯示我的查詢:http://sqlfiddle.com/#!3/fcebf/3 – milo2011

+0

看來結果加倍了。 – milo2011

回答

2

我不知道爲什麼您包括您在您的查詢汽車的表,因爲你不希望任何信息從那裏。

由於您將每次維修(例如,1月15日的維修)與具有相同車輛ID的每條記錄匹配的歷史記錄(其中有三個!),您將得到「雙倍」結果。其中兩場比賽是爲了駕駛約翰,所以你會得到兩個結果。

你想要的僅僅是匹配的驅動程序,根據你的歷史表,是在修理時驅動器!

所以,我首先匹配與實際匹配Receiveddate每個repairdate在歷史表:

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 
+0

謝謝,oerkelens。我已經添加了車輛表,因爲我想通過車牌號得到不同車輛的不同成本的總和。這是問題的第二部分。我已經添加了一個GROUP BY H.VehicleID,但它只適用於Repairs表。我怎麼做? http://sqlfiddle.com/#!3/fcebf/70 – milo2011

+0

我不確定我是否理解你的'來自更多表格的總和',因爲我只在1張表格中看到費用......我想如果你想要每輛車的總數',你應該使用一個不同的查詢 - 這個給你每個驅動程序的成本。除非你想每個車輛每個司機的成本,在這種情況下,你確實可以通過車輛ID進行分組。但是其他表格的其他成本並不容易添加,我認爲。也許更好的制定一個新的問題:) – oerkelens

+0

該數據庫有其他表,類似於修理表,其中還包含成本(輪胎表,保險表,..)我想生成一個報告,其中包含從這個總值桌子也是每個司機,而不是每輛車。我應該如何調整您提供的查詢,爲此目的..最終報告應包含(按給定的驅動程序和期限),以下列:車輛號碼|總修理成本|總輪胎成本| ... – milo2011

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這些重複行,但我建議你仔細檢查你的歷史記錄表中的數據