2013-06-21 2 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 <= ? 

매우 혼란 스럽지만이 쿼리를 만들어 행 집합 요약을 찾습니다. 최소 및 최대 타임 스탬프는 간단하지만 속도가 0이 아닌 0 인 행을 찾으면 추한 해킹을 수행했습니다. 나는 이것을 할 수있는 더 좋은 방법이 있다고 확신한다.더 나은 방법으로이 SQL 쿼리를 작성하는 좋은 방법은 무엇입니까?

업데이트 : "?" CodeIgniter의 미성숙 쿼리 빌더로 대체 될 것을 참고하십시오. 슬프게도 아직 명명 된 매개 변수를 지원하지 않습니다.

+0

당신의 조건'의 DeviceID ='를 포함하는 것을 잊지 않았다 당신의 처음 두 개의 서브 쿼리? – 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

나는 열 하위 쿼리를 제거합니다. 당신은 (내가 지금 fuelConsumption을 떠날거야) stopsDuration이 같은 tripDuration을 계산할 수 있습니다

당신은 Device 테이블의 단일 적용 행에 교차 - 결합하여 fuelComparison 하위 쿼리의 을 제거 할 수
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 <= ? 

.

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 조건을 사용하여 다른 하위 쿼리 테이블을 만들고 WHERE를 제거하는 것이 더 낫지 않습니까? – Shubham

+0

나는 그것에 대해 생각했지만'start' 및/또는'end' 및/또는'distanceTravelled' 값을 깨뜨릴 지 확실하지 않았습니다. 나는 이것을 시험 할 계획이 없었으므로 100 % 확실한 일을 한 후에 멈췄다. 너가 그것을 멀리 줄 수 있으면 너는 명확하게 응답으로 그것을 배치해야한다. 필자의 질문을 출발점으로 자유롭게 사용하자. 나는 전혀 문제가 없다. –

관련 문제