Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 找到超速的周期?_C#_Sql_Sql Server_Algorithm_Tsql - Fatal编程技术网

C# 找到超速的周期?

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

只是一些有趣的事情出现在我的脑海里。假设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查询或其他算法来实现这一点?

它不会那么简单,或者可以吗

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