btract运算符。暂时删除了order by,并将NVL替换为ISNULLHmm,这很奇怪。我不知道SQL Server不允许在内部select中使用order by。这可能会破坏滞后函数。。。尝试从内部selects中删除order by子句-这将解决

btract运算符。暂时删除了order by,并将NVL替换为ISNULLHmm,这很奇怪。我不知道SQL Server不允许在内部select中使用order by。这可能会破坏滞后函数。。。尝试从内部selects中删除order by子句-这将解决,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,btract运算符。暂时删除了order by,并将NVL替换为ISNULLHmm,这很奇怪。我不知道SQL Server不允许在内部select中使用order by。这可能会破坏滞后函数。。。尝试从内部selects中删除order by子句-这将解决该错误。希望SQL Server也能将分析函数中的order by子句应用于实际的select。让我看看如何获得SQL Server中两个datetime列之间的时间差。在Oracle中,您只需减去日期值,但在SQL Server中显然有所不同


btract运算符。暂时删除了order by,并将NVL替换为ISNULLHmm,这很奇怪。我不知道SQL Server不允许在内部select中使用order by。这可能会破坏滞后函数。。。尝试从内部selects中删除order by子句-这将解决该错误。希望SQL Server也能将分析函数中的order by子句应用于实际的select。让我看看如何获得SQL Server中两个datetime列之间的时间差。在Oracle中,您只需减去日期值,但在SQL Server中显然有所不同……请尝试使用datediff而不是subtract运算符。类似这样的东西应该会给你以分钟为单位的时间差:DateDiff(s,lead([井下时间])OVER(按[记录编号],[井下时间]%3600/60排序)。但不确定是否能够在datediff中将lead函数用作参数。如果没有,你必须再添加一个外部选择并在那里进行datediff…太棒了,谢谢@ErikE。您上次的查询耗时5秒。我发布的一条花了8秒,实际上需要查询的NoDuplicatesFlowTable部分。如果我把它拿出来,我们的表现相当。您的查询在这个数据集中很幸运(误报危险),请您解释一下我的查询没有处理的更复杂的数据好吗?另外,其他查询是如何执行的?表上的索引是什么?另外,我也有一个不一致的地方,我错误地使用了
[记录编号]
而不是
[井下时间]
——现在已经解决了。
Record Number    Downhole Time      Flow
-------------------------------------------
0        03/27/2013 19:23:48.582    1       *
58       03/27/2013 19:28:12.606    1   
137      03/27/2013 19:32:16.070    0       *
143      03/27/2013 19:33:59.070    0   
255      03/27/2013 19:40:14.070    0   
272      03/29/2013 14:43:55.071    1       *
289      03/29/2013 14:45:44.070    1   
293      03/29/2013 14:45:59.071    0       *
294      03/29/2013 14:46:10.070    0   
Record Number    Downhole Time      Flow
-------------------------------------------
0        03/27/2013 19:23:48.582    1       *
137      03/27/2013 19:32:16.070    0       *
272      03/29/2013 14:43:55.071    1       *
293      03/29/2013 14:45:59.071    0       *
cumulative time difference = 
  (03/27/2013 19:32:16.070 - 03/27/2013 19:23:48.582) 
+ (03/29/2013 14:45:59.071 - 03/29/2013 14:43:55.071) 
+ if there are more rows.
SELECT 
  un, 
  mytime, 
  flow,
  lead (mytime) OVER (ORDER BY UN) lead_time,
 (lead (mytime) OVER (ORDER BY UN) - mytime)*24*60 minutes
  FROM (  SELECT un,
                 mytime,
                 flow,
                 LAG (flow) OVER (ORDER BY UN) lag_val
            FROM test
        ORDER BY un) a
 WHERE a.flow != NVL (a.lag_val, 9999)
WITH FlowIntervals AS (
   SELECT
      FromTime = Min(D.[Downhole Time]),
      X.ToTime
   FROM
      dbo.vLog D
      OUTER APPLY (
         SELECT TOP 1 ToTime = D2.[Downhole Time]
         FROM dbo.vLog D2
         WHERE
            D.[Downhole Time] < D2.[Downhole Time]
            AND D.[Flow] <> D2.[Flow]
         ORDER BY D2.[Downhole Time]
      ) X
   WHERE D.Flow = 1
   GROUP BY X.ToTime
)
SELECT Sum(DateDiff(ms, FromTime, IsNull(ToTime, GetDate())) / 1000.0)
FROM FlowIntervals
;
WITH Ranks AS (
   SELECT
      Grp =
         Row_Number() OVER (ORDER BY [Downhole Time])
         - Row_Number() OVER (PARTITION BY Flow ORDER BY [Downhole Time]),
      [Downhole Time],
      Flow
   FROM dbo.vLog
), Ranges AS (
   SELECT
      Result = Row_Number() OVER (ORDER BY Min(R.[Downhole Time]), X.Num) / 2,
      [Downhole Time] = Min(R.[Downhole Time]),
      R.Flow, X.Num
   FROM
      Ranks R
      CROSS JOIN (SELECT 1 UNION ALL SELECT 2) X (Num)
   GROUP BY
      R.Flow, R.Grp, X.Num
), FlowStates AS (
   SELECT
      FromTime = Min([Downhole Time]),
      ToTime = CASE WHEN Count(*) = 1 THEN NULL ELSE Max([Downhole Time]) END,
      Flow = IsNull(Min(CASE WHEN Num = 2 THEN Flow ELSE NULL END), Min(Flow))
   FROM Ranges R
   WHERE Result > 0
   GROUP BY Result
)
SELECT
   ElapsedSeconds =
      Sum(DateDiff(ms, FromTime, IsNull(ToTime, GetDate())) / 1000.0)
FROM
   FlowStates
WHERE
   Flow = 1
;
FromTime                ToTime                  Flow
----------------------- ----------------------- ----
2013-03-27 19:23:48.583 2013-03-27 19:32:16.070 1
2013-03-27 19:32:16.070 2013-03-29 14:43:55.070 0
2013-03-29 14:43:55.070 2013-03-29 14:45:59.070 1
2013-03-29 14:45:59.070 NULL                    0
WITH StateChanges AS (
   SELECT
      [Downhole Time],
      Flow,
      Lag(Flow) OVER (ORDER BY [Downhole Time]) PrevFlow
   FROM
      dbo.vLog
), Durations AS (
   SELECT
      [Downhole Time], 
      Lead([Downhole Time]) OVER (ORDER BY [Downhole Time]) NextTime,
      Flow
   FROM
      StateChanges
   WHERE
      Flow <> PrevFlow
      OR PrevFlow IS NULL
)
SELECT ElapsedTime = Sum(DateDiff(ms, [Downhole Time], NextTime) / 1000.0)
FROM Durations
WHERE Flow = 1
;
Downhole Time         Flow  NotFlowTime  
-------------------------------------------  
2013-03-28 00:23:48.0000000 1   2013-03-28 00:32:16.0000000  
2013-03-28 00:32:16.0000000 0   2013-03-28 00:33:59.0000000  
2013-03-28 00:33:59.0000000 1   2013-03-28 00:40:14.0000000  
2013-03-28 00:40:14.0000000 0   2013-03-29 19:43:55.0000000  
2013-03-29 19:43:55.0000000 1   2013-03-29 19:45:44.0000000