2015-02-15 4 views
1

У меня есть база данных H2. Я хочу подсчитать среднее потребление топлива в отношении данных, которые я предоставил. Проблема в том, что то, что я получил, действительно беспорядочно. Это данные об использовании топлива для одного автомобиля.Выберите данные между двумя определенными строками

Это некоторые примерные данные:

| Amount | Date  | Start (km) | End (km) | 
+----------+------------+------------+----------+ 
| 35.5  | 2012-02-02 | 65000  | null  | 
| 36.7  | 2012-02-15 | null  | 66520 | 
| 44.5  | 2012-02-18 | null  | null  | 
| 33.8  | 2012-02-22 | 67000  | null  | 
| 44.5  | 2013-01-22 | null  | null  | 

Для подсчета среднего потребления топлива первого я вычисление разности между MIN (расстояние) и MAX (расстояние), чтобы сделать это я иметь следующий запрос:

SELECT 
    CASEWHEN((MAX(start)-MAX(end))>0, MAX(start), MAX(end)) 
    - 
    IFNULL(MIN(start),0) 
FROM fuel; 

для следующего шага я должен был бы SUM(Amount), но как я могу это сделать его только суммированием строк между 67000 и 65000?

Любая помощь очень ценится.

+0

Не может быть вам, потому что вы не указали критерии. Почему вы хотите получить только строки между 65000 и 67000? Является ли эта полная структура таблицы? –

+0

@MaciejLos Я хочу рассчитать расход топлива, но единственные действительные данные для меня находятся между этими рядами, так как после этого я не знаю, сколько было расстоянием путешествия – Wermerb

ответ

1

Я бы подойти к нему так:

SELECT SUM([amount])/SUM([end] - [start]) AS AverageFuelUsage 
FROM [fuel] 
WHERE [amount] IS NOT NULL 
AND [start] IS NOT NULL 
AND [end] IS NOT NULL 

NB: это исключает большое количество данных (в данной выборке, все это) - однако это важно.

  • Если вы не знаете количество топлива, используемого для поездки, это не означает, что топливо не использовалось, поэтому по умолчанию 0 является плохой идеей; лучше игнорировать эту строку и полагаться на полные данные.
  • Если вы не знаете начальное или конечное чтение, вы не знаете расстояния; снова вы не можете принять 0, поэтому игнорируйте эти плохие данные.

Если для всех записей у вас отсутствует хотя бы одно поле, вы можете уйти с кодом ниже - но я его не разрабатываю, если у вас даже 1% ваших записей есть полные данные для работы с.

SELECT AVG([amount])/(AVG([end]) - AVG([start])) AS AverageFuelUsage 
FROM [fuel] 

Идея здесь, если мы предположим, что на большом наборе данных средних значений данных из (т.е. большинство людей путешествуют подобные расстояния, с началом и завершением чтений также тяготеющих к некоторым средним) мы можем отрабатывать средние значения для каждый. Я не специалист по статистике и буду рассматривать любой результат, который дал бы с большим подозрением, но если это может быть лучше, вы можете получить, если у вас есть только плохие данные для работы и нужен результат.

Update

За обсуждение в комментариях, если вы записали каждую поездку и все показания для того же автомобиля, который вы можете найти первое значение с [пуск], последнее значение с [конец ], вычислите общее расстояние, пройденное во всех этих поездках, затем суммируйте все топливо, используемое на маршруте.

--ideally date is unique 
--if not this tries to work out the sequence of journeys based on start/end odometer readings 
--if they're both null and fall on the same day as the final [end] reading, assumes the null reading journey was prior to the [end] one 
declare @fuel table ([amount] float, [date] date, [start] int, [end] int) 
insert @fuel 
    values (35.5  , '2012-02-02' , 65000  , null ) 
     ,(36.7  , '2012-02-15' , null  , 66520 ) 
     ,(44.5  , '2012-02-18' , null  , null ) 
     ,(33.8  , '2012-02-22' , 67000  , null ) 
     ,(44.5  , '2013-01-22' , null  , null ) 

select j1.[start] 
, jn.[end] 
, sum(f.[amount]) [amount] 
, sum(f.[amount])/(jn.[end] - j1.[start]) LitresPerKm 
, (jn.[end] - j1.[start])/sum(f.[amount]) kmsPerLitre 

from 
(
    select top 1 [amount], [date], [start], [end] 
    from @fuel 
    where [start] is not null 
    order by [start] 
) j1 --first journey 
cross join 
( 
    select top 1 [amount], [date], [start], [end] 
    from @fuel 
    where [end] is not null 
    order by [end] desc 
) jn --last journey 
inner join @fuel f 
on f.[date] >= j1.[date] 
and (f.[end] <= j1.[start] or f.[end] is null) --in case multiple journeys on the same day & this is before our first start 
and f.[date] <= jn.[date] 
and (f.start <= jn.[end] or f.[start] is null) --in case multiple journeys on the same day & this is after our last end 
group by j1.[start],jn.[end] 
+0

Спасибо за ваш ответ. Я забыл упомянуть, что это 1 автомобиль другой путешествия, и я хотел бы подсчитать использование топлива этого конкретного автомобиля. – Wermerb

+0

Я протестировал ваше решение в базе данных, и это результат: 0.00917. Я не думаю, что это сработает: S – Wermerb

+0

Было ли это использование первого или второго SQL? FYI: Что касается статистики (т. Е. Мои проблемы с обоснованиями за вторым SQL), я попросил математиков для их ввода: https: // stats.stackexchange.com/questions/137769/calculating-average-fuel-consumption-with-no-complete-data. – JohnLBevan

Смежные вопросы