2016-01-14 52 views
-6

我有駕駛速度和路段的表:我應該如何計算多段路段的平均速度?

driver_lpr | segment | speed 
    0000001  |  A  |  30 
    0000002  |  B  |  60 
    0000003  |  A  |  50 
    0000004  |  A  |  100 
    0000005  |  B  |  60 

而且我希望有每段

segment | average speed 
    A  |   47.368 
    B  |   60 

平均速度的表怎麼能在SQL中完成?

+2

元下討論[我怎麼能展示給選民一個問題是像看起來那樣微不足道?](http://meta.stackoverflow.com/q/314789) –

+2

這可能如果OP提到他期望的'平均值'不是'你的日常平均值',那將會有所幫助。 TBH,我從來沒有聽說過'諧波的意思',我花了一段時間才意識到他的例子結果是'奇怪的'=) – deroby

+2

他*可能*不知道,@deroby(亞歷杭德羅,你能澄清嗎?) - 不會是第一次用某種算術平均來計算平均速度,並在沒有意識到原因的情況下得到不正確的結果。 – Shog9

回答

20

當平均速度時,需要harmonic mean

直線前進AVG()方法是錯誤的,算術平均值會產生平均速度的錯誤結果。

沒有爲調和平均數沒有預先定義的功能,但它可能與此查詢來實現:

SELECT segment, 
     COUNT(*)/SUM(1e0/speed) AS avg_speed 
FROM T 
GROUP BY segment 

SQL Fiddle

+0

如果段的距離相同,如果時間間隔相同,那麼標準算術平均值就足夠,如果既不需要加權諧波或算術平均值,也是如此。 –

+0

很好的答案。 ;)upvoted。 – Ian

3

這是有點複雜,但會照顧0速度也。我有兩個類似的查詢,根據不同的情況做。

假設您的源表如下所示。

+-------------+----------+-------+ 
| driver_lpr | segment | speed | 
+-------------+----------+-------+ 
| 0000001 | A  | 30 | 
| 0000002 | B  | 60 | 
| 0000003 | A  | 50 | 
| 0000004 | A  | 100 | 
| 0000005 | B  | 60 | 
| 0000006 | B  |  0 | 
| 0000007 | C  |  0 | 
+-------------+----------+-------+ 

我已經增加了2個新行,速度爲0

情況1:在段B

  • 添加一個0速度的,將給出平均速度作爲 40(60*2+0*1)/(2+1)
  • 增加了一個新段,C0 速度會給平均速度爲0

所以輸出將

+----------+-------------------+ 
| segment | average_speed | 
+----------+-------------------+ 
| A  | 47.36842105263158 | 
| B  | 40    | 
| C  | 0     | 
+----------+-------------------+ 

SQLFiddle Demo CASE 1

案例2:

  • 將有在B平均速度添加 0的沒有變化。
  • 但是,新段C將具有0的平均速度。

輸出將是

+----------+-------------------+ 
| segment | average_speed | 
+----------+-------------------+ 
| A  | 47.36842105263158 | 
| B  | 60    | 
| C  | 0     | 
+----------+-------------------+ 

SQLFiddle Demo CASE 2

查詢爲情況1:

with tbl1 as 
    (SELECT segment, 
    case when speed = 0 then cast(0 as float) else 
    cast(1 as float)/cast(speed as float) 
    end as newspeed 
    FROM T 
    ), 
tbl2 as 
    (
     select segment,cast(1 as float)/avg(newspeed) as avgspeed,count(*) as cnt 
     from tbl1 
     where newspeed <> 0 
     group by segment 
    union 
     select segment,0 as avgspeed,count(*) as cnt 
     from tbl1 
     where newspeed =0 
     group by segment 
    ) 
select segment, 
    sum(avgspeed*cnt)/sum(cnt) as "average_speed" 
from tbl2 
group by segment 

查詢的情況2

with tbl1 as 
    (SELECT segment, 
    case when speed = 0 then cast(0 as float) else 
    cast(1 as float)/cast(speed as float) 
    end as newspeed 
    FROM T 
    ), 
tbl2 as 
    (
     select segment,cast(1 as float)/avg(newspeed) as avgspeed,count(*) as cnt 
     from tbl1 
     where newspeed <> 0 
     group by segment 
    union 
     select segment,0 as avgspeed,count(*) as cnt 
     from tbl1 
     where newspeed =0 
     group by segment 
    ) 
select segment, 
    sum(avgspeed) as "average_speed" 
from tbl2 
group by segment 
+1

怎麼能有0的速度?這意味着他們是靜止的,因此無法完成任何路段。 –

+0

只是想涵蓋所有可能的情況。 – Utsav