在SQL Server中使用LAG for SUM

时间:2017-07-16 08:14:00

标签: sql sql-server sql-server-2014

我有一个GPS应用程序,可以将数据保存到下表:

CREATE TABLE [dbo].[T_Tracking]
(
    [id]          [int] IDENTITY(1,1) NOT NULL,
    [IMEI]        [nvarchar](50) NULL,
    [TrackTime]   [datetime] NULL,
    [Longitude]   [nvarchar](50) NULL,
    [Lattitude]   [nvarchar](50) NULL,
    [speed]       [float] NULL,
    [CarID]       [int] NULL,
    [Country]     [nvarchar](50) NULL,
    [City]        [nvarchar](50) NULL,
    [Area]        [nvarchar](50) NULL,
    [Street]      [nvarchar](50) NULL,
    [FullAddress] [nvarchar](150) NULL,
    [Distance]    [float] NULL
)

我需要获得每天停车的总时间和每天的总驾驶时间:

表样本数据

enter image description here

到目前为止我尝试过:

SELECT carid, SUM(DATEDIFF(minute,  a.trackold, a.TrackTime)) as LostTime ,TrackDay FROM (SELECT carid, TrackTime, LAG( TrackTime, 1, Null) OVER (PARTITION BY  carid  ORDER BY carid) as trackold ,
      CONVERT(date, TrackTime) as TrackDay
  FROM T_Tracking) a  
  group by carid,TrackDay

查询结果:

enter image description here

查询几乎正确但我需要获得列速度(其中速度&lt; 3表示停止,速度&gt; 3表示驱动器),例如, car1停车10小时车程14小时 (停车速度<3)

由于

是gps系统 每辆车每1分钟插入一条记录 记录包含速度和当前日期时间 需要计算汽车每天停车多少以及驾驶多少 停止不是速度= 0它是速度<3 预计

select 'Car1' as CarID, '01/01/2017' as TrackDay , 240 as StopTimeInMinutes , 300 as DriveTimeInMinutes

编辑 sqlfiddle

http://www.sqlfiddle.com/#!6/cb633d 结果 enter image description here

新编辑

      SELECT 
    carid
  , TrackTime
  , LAG( TrackTime, 1, Null) OVER (PARTITION BY  carid  ORDER BY carid) as trackold
  , CONVERT(date, TrackTime) as TrackDay
  , speed,DATEDIFF(minute, LAG( TrackTime, 1, Null) OVER (PARTITION BY  carid  ORDER BY carid),TrackTime)
FROM T_Tracking

结果

enter image description here

问题是当另一天的滞后记录必须存在记录及其在同一天滞后的情况时

1 个答案:

答案 0 :(得分:0)

首先,通过随机化和SSMSBoost ~50行)定义必要的结构和一些样本数据:

--DROP TABLE #T_Tracking
CREATE TABLE #T_Tracking
(
    [id]          [int] IDENTITY(1,1) NOT NULL,
    [TrackTime]   [datetime] NULL,
    [speed]       [float] NULL,
    [CarID]       [int] NULL
)
-- Those two lines made me the random data.
--INSERT INTO #T_Tracking VALUES (CURRENT_TIMESTAMP, RAND() * 10, 1001)
--INSERT INTO #T_Tracking SELECT TOP 1 DATEADD(MINUTE, 1, TrackTime), RAND() * 10, 1001 FROM #T_Tracking WHERE CarID = 1001 ORDER BY id DESC
SET IDENTITY_INSERT #T_Tracking ON
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES (1,CAST('20170716 15:55:03.350' as DATETIME),0.16923905811553, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES (2,CAST('20170716 15:55:03.367' as DATETIME),2.07898632701893, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES (3,CAST('20170716 15:55:03.367' as DATETIME),1.80666718899698, 3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES (4,CAST('20170716 15:56:03.350' as DATETIME),9.94864912346075, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES (5,CAST('20170716 15:56:03.367' as DATETIME),7.51657570710667, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES (6,CAST('20170716 15:56:03.367' as DATETIME),6.70713362404461, 3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES (7,CAST('20170716 15:57:03.350' as DATETIME),4.45078903833255, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES (8,CAST('20170716 15:57:03.367' as DATETIME),6.47045595046756, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES (9,CAST('20170716 15:57:03.367' as DATETIME),5.24162088372108, 3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(10,CAST('20170716 15:58:03.350' as DATETIME),8.87269367433288, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(11,CAST('20170716 15:58:03.367' as DATETIME),7.94399400473739, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(12,CAST('20170716 15:58:03.367' as DATETIME),6.34658897830318, 3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(13,CAST('20170717 15:55:03.397' as DATETIME),8.29103012350227, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(14,CAST('20170717 15:55:03.397' as DATETIME),6.59994175020258, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(15,CAST('20170717 15:55:03.397' as DATETIME),5.59272074948864, 3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(16,CAST('20170717 15:56:03.397' as DATETIME),2.24101274328892, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(17,CAST('20170717 15:56:03.397' as DATETIME),3.25396492167535, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(18,CAST('20170717 15:56:03.397' as DATETIME),8.95021218987194, 3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(19,CAST('20170717 15:57:03.397' as DATETIME),0.554494328077911,1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(20,CAST('20170717 15:57:03.397' as DATETIME),3.97927461327881, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(21,CAST('20170717 15:57:03.397' as DATETIME),0.440008191277681,3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(22,CAST('20170717 15:58:03.397' as DATETIME),5.97204548751938, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(23,CAST('20170717 15:58:03.397' as DATETIME),5.60860061472591, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(24,CAST('20170717 15:58:03.397' as DATETIME),0.593327169646068,3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(25,CAST('20170718 15:55:03.427' as DATETIME),4.67974215928374, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(26,CAST('20170718 15:55:03.427' as DATETIME),3.51345008036671, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(27,CAST('20170718 15:55:03.427' as DATETIME),2.60753164190143, 3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(28,CAST('20170718 15:56:03.427' as DATETIME),3.20546406676272, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(29,CAST('20170718 15:56:03.427' as DATETIME),9.32640254306593, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(30,CAST('20170718 15:56:03.427' as DATETIME),4.37254464064582, 3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(31,CAST('20170718 15:57:03.427' as DATETIME),8.1614334079022,  1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(32,CAST('20170718 15:57:03.427' as DATETIME),7.56329435049565, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(33,CAST('20170718 15:57:03.427' as DATETIME),5.16454224115922, 3003)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(34,CAST('20170718 15:58:03.427' as DATETIME),2.81984150644997, 1001)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(35,CAST('20170718 15:58:03.427' as DATETIME),8.89421657221517, 2002)
INSERT INTO [#T_Tracking]([id],[TrackTime],[speed],[CarID]) VALUES(36,CAST('20170718 15:58:03.427' as DATETIME),8.20605160683511, 3003)
SET IDENTITY_INSERT #T_Tracking OFF

其次,修订后的查询(答案部分)。我只是简单地纳入了 dnoeth 的评论,有些甚至我申请超出了他的注意范围。但是对于ORDER,我使用了与他不同的列,但它们的行为应该相同:

SELECT
    carid
  , CONVERT(date, tracktime) AS DAYDAY
  , SUM(CASE WHEN speed <  3 THEN 0 ELSE DATEDIFF(SECOND, T.trackold, T.TrackTime) END) AS 'SPEEDING'
  , SUM(CASE WHEN speed >= 3 THEN 0 ELSE DATEDIFF(SECOND, T.trackold, T.TrackTime) END) AS 'PARKED'
FROM (
    SELECT speed, tracktime, carid, LAG(TrackTime, 1, Null) OVER (PARTITION BY carid, CONVERT(date, tracktime) ORDER BY id ASC) as trackold
    FROM #T_Tracking
) AS T
GROUP BY CARID, CONVERT(date, tracktime)

第三,输出基于示例(第一次做这些,提示/改进赞赏):

carid       DAYDAY        SPEEDING    PARKED
----------- ----------    ----------- -----------
1001        2017-07-16    180         0
2002        2017-07-16    180         0
3003        2017-07-16    180         0
1001        2017-07-17    60          120
2002        2017-07-17    180         0
3003        2017-07-17    60          120
1001        2017-07-18    120         60
2002        2017-07-18    180         0
3003        2017-07-18    180         0

提醒,请修改&amp;防范任何NULL'ERROR'问题。