C# 找到超速的周期?
只是一些有趣的事情出现在我的脑海里。假设SQL Server中有这样一个表: 地方 速度 时间 例如:C# 找到超速的周期?,c#,sql,sql-server,algorithm,tsql,C#,Sql,Sql Server,Algorithm,Tsql,只是一些有趣的事情出现在我的脑海里。假设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
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查询或其他算法来实现这一点?它不会那么简单,或者可以吗
SELECT
Location,
Velocity,
Time,
CASE WHEN Velocity > @SpeedBarrier THEN 1 ELSE 0 END AS IsOverSpeed
FROM
SpeedTable
假设它匹配,那么它将为false,遵循下面的SQL查询 挑选 地点,速度,时间,
velocity>speedLimit=true或velocity您可以通过使用CTE实现这一点 下面的查询针对SQL Server的Adventure works演示表工作,其速度限制为7 这一点受到关于SO的另一个问题的强烈启发: 以下几点应该适合你:
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
我使用了下面的部分来获取一些数据,我在兼容模式80ATM上,所以我没有时间字段,并且使用INT作为时间戳
DECLARE @Info TABLE (Location INT IDENTITY, Velocity INT, [Time] INT);
INSERT INTO @Info (Velocity, [Time]) VALUES (40, 80);
INSERT INTO @Info (Velocity, [Time]) VALUES (35, 120);
INSERT INTO @Info (Velocity, [Time]) VALUES (45, 125);
INSERT INTO @Info (Velocity, [Time]) VALUES (50, 150);
INSERT INTO @Info (Velocity, [Time]) VALUES (60, 165);
INSERT INTO @Info (Velocity, [Time]) VALUES (48, 175);
INSERT INTO @Info (Velocity, [Time]) VALUES (40, 180);
INSERT INTO @Info (Velocity, [Time]) VALUES (35, 195);
INSERT INTO @Info (Velocity, [Time]) VALUES (50, 200);
INSERT INTO @Info (Velocity, [Time]) VALUES (70, 210);
INSERT INTO @Info (Velocity, [Time]) VALUES (50, 215);
INSERT INTO @Info (Velocity, [Time]) VALUES (40, 220);
INSERT INTO @Info (Velocity, [Time]) VALUES (45, 225);
INSERT INTO @Info (Velocity, [Time]) VALUES (45, 230);
假设您的位置是必须通过的固定点,以完成以下操作,将产生所需的输出。我将其分为多个阶段,以明确每个部分的作用
DECLARE @Limit INT;
SET @Limit = 40;
WITH Stage1 ([Location], [Velocity], [Time]) AS (
SELECT * FROM @Info WHERE [Velocity] > @Limit
), Stage2 (Start) AS (
SELECT [Time]
FROM [Stage1]
WHERE ([Location] - 1) NOT IN (SELECT [Location] FROM [Stage1])
), Stage3 ([Start], [Stop]) AS (
SELECT [Start]
, (SELECT MIN([Time]) FROM [Stage1] WHERE ([Location] + 1) NOT IN (SELECT [Location] FROM [Stage1]) AND [Time] > [Stage2].[Start])
FROM Stage2
)
SELECT *
FROM Stage3
关键是要将速度>速度障碍的时间聚合为时间跨度-s?不太清楚。你期望的输出是什么?我期望的输出是,汽车从何时到何时超速,而不仅仅是时间范围。你对车速随时间变化的模型是什么?车速是按时间间隔记录的。我忽略了加速度,所以我们只依赖于表中的数据:从技术上讲,第二列应该是“速度”,而不是“速度”,因为没有方向分量。您的查询似乎列出了所有超速记录,而不是仅列出超速时段。现在没有一个真正的表要测试:@Vimvq1987:是的,这就是为什么我的答案如此不情愿的原因-刚刚测试,您的查询返回所有记录,刚刚添加了一个新字段IsOverSpeed 1/0:不确定为什么会被降级,当然有人愿意通过惩罚其他人来获得声誉,算了吧。。。
DECLARE @Limit INT;
SET @Limit = 40;
WITH Stage1 ([Location], [Velocity], [Time]) AS (
SELECT * FROM @Info WHERE [Velocity] > @Limit
), Stage2 (Start) AS (
SELECT [Time]
FROM [Stage1]
WHERE ([Location] - 1) NOT IN (SELECT [Location] FROM [Stage1])
), Stage3 ([Start], [Stop]) AS (
SELECT [Start]
, (SELECT MIN([Time]) FROM [Stage1] WHERE ([Location] + 1) NOT IN (SELECT [Location] FROM [Stage1]) AND [Time] > [Stage2].[Start])
FROM Stage2
)
SELECT *
FROM Stage3