我突然想到了一些有趣的事情。假设我们有一个像这样的表(在 SQL Server 中):
- 地点
- 速度
- 时间
例如:
Location Velocity Time
1 40 1:20
2 35 2:00
3 45 2:05
4 50 2:30
5 60 2:45
6 48 2:55
7 40 3:00
8 35 3:15
9 50 3:20
10 70 3:30
11 50 3:35
12 40 3:40
假设速度障碍是40kph,输出是这样的
Starttime Endtime
2:05 3:00
3:20 3:35
确定超速周期的最佳方法是什么(定义了速度障碍)?我的第一个想法是将表格加载到数组中,然后遍历数组以找到这些句点:
(伪C#代码)
bool isOverSpeed = false;
for (int i =0;i<arr.Length;i++)
{
if (!isOverSpeed)
if (arr[i].Velocity > speedBarrier)
{
#insert the first record into another array.
isOverSpeed = true;
}
if(isOverSpeed)
if (arr[i].Velocity < speedBarrier)
{
#insert the record into that array
isOverSpeed = false;
}
}
它有效,但有点“不是很有效”。是否有“更智能”的方式,例如 T-SQL 查询或其他算法来执行此操作?
最佳答案
您可以使用 CTE ( Common Table Expressions ) 实现这一点。
下面的查询针对 SQL Server 的 Adventure Works 演示表(“速度限制”为 7)。
这受到关于 SO 的另一个问题的强烈启发:GROUP BY for continuous rows in SQL .
with CTE as (
select
ROW_NUMBER() over(order by SalesTaxRateID) as RowNo
, *
from
Sales.SalesTaxRate
)
, MyLogGroup as (
select
l.*
,(select
max(SalesTaxRateID)
from
CTE c
where
not exists (select * from CTE
where RowNo = c.RowNo-1
and TaxRate > 7
and c.TaxRate > 7)
and c.SalesTaxRateID <= l.SalesTaxRateID) as GroupID
from
Sales.SalesTaxRate l)
select
min(SalesTaxRateID) as minimum
, max(SalesTaxRateID) as maximum
, avg(TaxRate)
from
MyLogGroup
group by
GroupID
having
min(TaxRate) > 7
order by
minimum
这些方面的内容应该适合您:
with CTE as (
select
ROW_NUMBER() over(order by [Time]) as RowNo
, *
from
<table_name>
)
, MySpeedGroup as (
select
s.*
,(select
max([Time])
from
CTE c
where
not exists (select * from CTE
where RowNo = c.RowNo-1
and Velocity > <speed_limit>
and c.Velocity > <speed_limit>)
and c.[Time] <= s.[Time]) as GroupID
from
<table_name> l)
select
min([Time]) as minimum
, max([Time]) as maximum
, avg([Velocity]) -- don't know if you want this
from
MySpeedGroup
group by
GroupID
having
min(Velocity) > <speed_limit>
order by
minimum
关于c# - 找到超速的时期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2947963/