Select 2 个定义行之间的数据
Select data between 2 defined rows
我有一个H2数据库。我想计算关于我提供的数据的平均燃料使用量。问题是我得到的东西真的很乱。这是1辆车的油耗数据。
这是一些示例数据:
| 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 之间的行求和?
非常感谢任何帮助。
我会这样处理:
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
注意:这排除了很多数据(在您的示例数据中,所有数据)- 但这很重要。
- 如果你不知道一次旅行使用了多少燃料,那并不意味着没有使用燃料,所以默认为 0 是个坏主意;最好忽略这一行并依赖完整的数据。
- 不知起止,不知远近;同样,您不能假设为 0,因此请忽略此错误数据。
如果对于所有记录,您至少缺少一个字段,您可以使用下面的代码 - 但即使您的 1% 的记录有完整数据可供使用,我也不会设计它.
SELECT AVG([amount]) / ( AVG([end]) - AVG([start]) ) AS AverageFuelUsage
FROM [fuel]
这里的想法是,如果我们假设在一个大数据集上数据取平均值(即大多数人行进的距离相似,开始和结束读数也趋向于某个平均值),我们可以计算出每个数据的平均值。我不是统计学家,并且会以很多怀疑的态度对待这给出的任何结果,但是如果您只有不良数据可以使用并且需要结果,那么如果这可能是您可以获得的最好结果。
更新
根据评论中的讨论,如果您记录了每一次旅程并且所有读数都针对同一辆车,您可以找到带有 [start] 的第一个值,带有 [end] 的最后一个值,计算总距离在所有这些旅程中旅行,然后总结途中使用的所有燃料。
--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]
我有一个H2数据库。我想计算关于我提供的数据的平均燃料使用量。问题是我得到的东西真的很乱。这是1辆车的油耗数据。
这是一些示例数据:
| 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 之间的行求和?
非常感谢任何帮助。
我会这样处理:
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
注意:这排除了很多数据(在您的示例数据中,所有数据)- 但这很重要。
- 如果你不知道一次旅行使用了多少燃料,那并不意味着没有使用燃料,所以默认为 0 是个坏主意;最好忽略这一行并依赖完整的数据。
- 不知起止,不知远近;同样,您不能假设为 0,因此请忽略此错误数据。
如果对于所有记录,您至少缺少一个字段,您可以使用下面的代码 - 但即使您的 1% 的记录有完整数据可供使用,我也不会设计它.
SELECT AVG([amount]) / ( AVG([end]) - AVG([start]) ) AS AverageFuelUsage
FROM [fuel]
这里的想法是,如果我们假设在一个大数据集上数据取平均值(即大多数人行进的距离相似,开始和结束读数也趋向于某个平均值),我们可以计算出每个数据的平均值。我不是统计学家,并且会以很多怀疑的态度对待这给出的任何结果,但是如果您只有不良数据可以使用并且需要结果,那么如果这可能是您可以获得的最好结果。
更新
根据评论中的讨论,如果您记录了每一次旅程并且所有读数都针对同一辆车,您可以找到带有 [start] 的第一个值,带有 [end] 的最后一个值,计算总距离在所有这些旅程中旅行,然后总结途中使用的所有燃料。
--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]