我有一张驾驶员速度和路段的表格:
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中完成?
答案 0 :(得分:20)
平均速度时,需要harmonic mean。
直接AVG()
方法是错误的,算术平均值会产生错误的平均速度结果。
调和均值没有预定义函数,但可以通过此查询实现:
SELECT segment,
COUNT(*)/SUM(1e0/speed) AS avg_speed
FROM T
GROUP BY segment
答案 1 :(得分:3)
这有点复杂,但也会照顾0
速度。我有2个类似的查询可以根据不同的场景来完成。
假设您的源表如下所示。
+-------------+----------+-------+
| 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:
0
段中添加B
速度,将平均速度设为
40
(60*2+0*1)/(2+1)
。 C
添加新细分0
速度将平均速度设为0
因此输出
+----------+-------------------+
| segment | average_speed |
+----------+-------------------+
| A | 47.36842105263158 |
| B | 40 |
| C | 0 |
+----------+-------------------+
的 SQLFiddle Demo CASE 1
强> 的
案例2:
B
的平均速度不会随着a的增加而改变
0
。 C
的平均速度为0
。输出
+----------+-------------------+
| segment | average_speed |
+----------+-------------------+
| A | 47.36842105263158 |
| B | 60 |
| C | 0 |
+----------+-------------------+
查询案例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
查询Case2
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