c# - 找到超速的时期?

标签 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         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/

相关文章:

sql - Oracle 是否有相当于 SQL Server OUTPUT INSERTED.* 的功能?

mysql - 关于having 子句和where 子句的问题

sql - 在您的星型模式表设计中包含关系有什么好处吗?

sql-server - SQL Server Case 语句在 Delphi TADODataSet 中不起作用

sql - 按周汇总,即使是空行

c# - 在循环中使用 FindControl 获取以编程方式添加的文本框的值

c# - 为什么使用 1024 作为缓冲区?

sql-server - 为什么我的 tsql varbinary 数据被截断

c# - NumberFormatInfo NumberDecimalDigits 不工作(?)

javascript - 通过Request.Form传递二维数组(或对象数组)?