【问题标题】:Using LAG for SUM in SQL Server在 SQL Server 中使用 LAG 进行 SUM
【发布时间】:2017-07-16 08:13:59
【问题描述】:

我有一个 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
)

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

表格样本数据

到目前为止我所尝试的:

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

查询结果:

查询几乎正确,但我需要获取列速度(其中速度 3 表示驱​​动),例如car1 停车 10 小时 驾驶 14 小时 (停车速度

谢谢

是gps系统 每辆车每 1 分钟插入一条记录 记录包含速度和当前日期时间 计算汽车每天停了多少次以及开多少次所需的 stop 不是 speed=0 它是 speed

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

编辑 sqlfiddle

http://www.sqlfiddle.com/#!6/cb633d 结果

新编辑

      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

结果

问题是当另一天的滞后记录必须有一个条件,即记录和它的滞后在同一天

【问题讨论】:

  • 尝试在到达SUM 之前有一列将3 分开,可能是通过CASE,并将该列包含在分组中。此外,为了帮助我们理解和测试,可能会添加一些示例数据作为INSERT 语句以及该特定示例数据的当前和预期输出。
  • 添加了 sqlfiddle 链接
  • 是的,这个示例似乎与小提琴或问题的图像并不真正相关(这很麻烦,因为它们是图像),但是,试试这个? sqlfiddle.com/#!6/cb633d/6/0
  • 谢谢它已经接近了,但我需要每辆车每天记录一个记录,其中有一列是停止多少,另一列是正在运行,请查看我的编辑我需要 SUM(DATEDIFF(分钟,a. trackold, a.TrackTime)) where speed3 as drivetime

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


【解决方案1】:

首先,通过随机化和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

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

【讨论】:

  • 谢谢,但还不是每辆车每天都必须有一个记录,在您的回答中包含驾驶总和停车总和汽车每天有多个记录
  • @MaherKhalil,没看懂你的评论,但我发现了一堆错误并修复了它们,请再检查一遍。
  • 谢谢,但我在超速和停车时有奇怪的数字,这个数字应该小于 1440(一天中的总分钟数),但我得到的数字更大,我已经插入了结果图像
  • order by carid,应该是order by TrackTime。您可能需要将CONVERT(date, TrackTime) 添加到PARTITION BY
  • @MaherKhalil:另外,您应该根据秒计算,最后除以 60 得到分钟。见sqlfiddle.com/#!6/cb633d/15
猜你喜欢
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
  • 2017-03-06
  • 2011-09-18
  • 2010-10-25
  • 2020-06-29
  • 2018-12-12
  • 2014-03-14
相关资源
最近更新 更多