2013-06-21 115 views
2
SELECT 
    MAX(timestamp) as end, 
    MIN(timestamp) as start, 
    (MAX(odometerKM) - MIN(odometerKM)) as distanceTravelled, 
    (SELECT COUNT(*) FROM EventData WHERE speedKPH = 0 AND timestamp >= ? AND timestamp <= ? AND deviceID = ?) as stopsDuration, 
    (SELECT COUNT(*) FROM EventData WHERE speedKPH != 0 AND timestamp >= ? AND timestamp <= ? AND deviceID = ?) as tripDuration, 
    (MAX(odometerKM) - MIN(odometerKM))/(SELECT fuelEconomy FROM Device WHERE deviceID = ?) as fuelConsumption 
FROM EventData 
WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ? 

非常令人困惑,但我創建了此查詢來查找行集合的摘要。最小和最大時間戳很簡單,但要找到速度爲零而非零的行的COUNT,我做了一個醜陋的黑客。我相信有更好的方法來做到這一點?以更好的方式寫這個SQL查詢的好方法是什麼?

更新:「?」請參閱由CodeIgniter的一個不成熟的查詢生成器替換。可悲的是,它尚不支持命名參數。

+0

你沒忘了,包括在條件'WHERE設備ID ='你前兩個子查詢? – RandomSeed

+0

@Yak:是的。讓我編輯。 – Shubham

+0

此外,它看起來像相同的兩個子查詢實際上計算一個*號*的事件('COUNT()')而不是持續時間? – RandomSeed

回答

0

你應該包含DeviceID,所以它是有道理的。試試這個:

SELECT 
DeviceID, 
MAX(timestamp) as end, 
MIN(timestamp) as start, 
(MAX(odometerKM) - MIN(odometerKM)) as distanceTravelled, 
SUM (
    case speedKPH 
    when 0 then 1 
    else 0 
    end) as stopsDuration, 

SUM (
    case speedKPH 
    when 0 then 0 
    else 1 
    end) as tripDuration, 

(MAX(odometerKM) - MIN(odometerKM))/Device.fuelEconomy as fuelConsumption 

FROM EventData 
Join Device ON Device.deviceID = EventData.deviceID 

WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ? 

GROUP BY DeviceID 
0

我擺脫了列子查詢。你可以計算stopsDurationtripDuration這樣的(我離開了fuelConsumption現在):

SELECT 
    MAX(timestamp) as end, MIN(timestamp) as start, 
    MAX(odometerKM) - MIN(odometerKM) as distanceTravelled, 
    COUNT(speedKPH = 0 AND timestamp >= ? AND timestamp <= ?) as stopsDuration 
    COUNT(speedKPH != 0 AND timestamp >= ? AND timestamp <= ?) as tripDuration 
FROM EventData WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ? 

您可以通過交叉連接到Device表的單排適用擺脫fuelComparison子查詢的

SELECT 
    (MAX(odometerKM) - MIN(odometerKM))/dv.fuelEconomy as fuelConsumption 
FROM 
    EventData, 
    (SELECT Device.fuelEconomy FROM Device WHERE DeviceId = ?) dv 
WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ? 

把它放在一起,你會得到這一點,這(至少在紙)應該會更快:

SELECT 
    MAX(timestamp) as end, MIN(timestamp) as start, 
    MAX(odometerKM) - MIN(odometerKM) as distanceTravelled, 
    COUNT(speedKPH = 0 AND timestamp >= ? AND timestamp <= ?) as stopsDuration 
    COUNT(speedKPH != 0 AND timestamp >= ? AND timestamp <= ?) as tripDuration, 
    (MAX(odometerKM) - MIN(odometerKM))/dv.fuelEconomy as fuelConsumption 
FROM 
    EventData, 
    (SELECT Device.fuelEconomy FROM Device WHERE DeviceId = ?) dv 
WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ? 
+0

爲了減少它,不是最好創造另一個子查詢表與WHERE條件和消除所有的地方? – Shubham

+0

我想過,但我不確定它是否會打破'start'和/或'end'和/或'distanceTravelled'值。我從來沒有打算測試這個,所以我在做了100%確定的事情之後就停止了。如果你可以減少這一點,你絕對應該把它作爲答案。隨意使用我的查詢作爲起點 - 我根本沒有問題:) –

相關問題