【问题标题】:Substract date from previous row by group SQL query按组 SQL 查询从上一行中减去日期
【发布时间】:2019-10-04 08:20:38
【问题描述】:

数据

id      date        
2380    10/30/12 09:00:00 
2380    10/30/12 09:05:00   
2380    10/30/12 09:10:00   
2380    10/30/12 09:15:00    
2381    10/30/12 10:00:00   
2381    10/30/12 10:05:00  
2381    10/30/12 10:10:00   
2381    10/30/12 10:15:00   
2382    10/30/12 11:00:00
2382    10/30/12 11:05:00
2382    10/30/12 10:10:00
2382    10/30/12 10:15:00

我想要以下解决方案

id      date                 duration        
2380    10/30/12 09:00:00    00:00:00 
2380    10/30/12 09:05:00    00:05:00   
2380    10/30/12 09:10:00    00:10:00
2380    10/30/12 09:15:00    00:15:00
2381    10/30/12 10:00:00    00:00:00
2381    10/30/12 10:05:00    00:05:00
2381    10/30/12 10:10:00    00:10:00
2381    10/30/12 10:15:00    00:15:00
2382    10/30/12 11:00:00    00:00:00
2382    10/30/12 11:05:00    00:05:00
2382    10/30/12 10:10:00    00:10:00
2382    10/30/12 10:15:00    00:10:00

我试图理解以下线程背后的逻辑,但很难理解。

Substract date from previous row by group (using R)

select id, date, date - (select min(date) from date group by id) as duration 
from date

我得到的最接近的是一个 id。

【问题讨论】:

  • 你试过LAG功能吗?
  • 没有。请问能告诉我怎么用吗?谢谢

标签: sql-server


【解决方案1】:

试试下面这个例子,希望这是你想要的输出,

declare @t1 table
(
    id int,
    dtdate datetime
)

insert into @t1 values(2380,'10/30/12 09:00:00') 
insert into @t1 values(2380,'10/30/12 09:05:00')   
insert into @t1 values(2380,'10/30/12 09:10:00')   
insert into @t1 values(2380,'10/30/12 09:15:00')    
insert into @t1 values(2381,'10/30/12 10:00:00')   
insert into @t1 values(2381,'10/30/12 10:05:00')  
insert into @t1 values(2381,'10/30/12 10:10:00')   
insert into @t1 values(2381,'10/30/12 10:15:00')   
insert into @t1 values(2382,'10/30/12 11:00:00')
insert into @t1 values(2382,'10/30/12 11:05:00')
insert into @t1 values(2382,'10/30/12 10:10:00')
insert into @t1 values(2382,'10/30/12 10:15:00')

;WITH CTE AS (
SELECT
rownum = ROW_NUMBER() OVER (partition by id ORDER BY id,dtDate),
id,dtDate
FROM @t1 p
)
SELECT
a.id,
a.dtDate,
CASE WHEN prev.dtdate is NULL THEN '00:00:00' ELSE convert(nvarchar(8),a.dtdate- prev.dtdate,108) END as duration 
FROM CTE a
LEFT JOIN CTE prev ON a.id = prev.id AND prev.rownum = a.rownum - 1

【讨论】:

  • 谢谢,但我收到此错误消息,指出 LAG 被识别为内置函数。还有什么办法吗?
  • @Muffin13 - 没有 LAG 功能的编辑代码,因为 LAG 是在 SQL Server 2012 及更高版本中引入的
【解决方案2】:

我的方法的关键是找到每个 id 的最小日期值,我称之为 ReferenceDate。然后我加入主表并使用 DATEDIFF() 函数进行日期数学运算,并使用样式 108 使用 CONVERT() 函数将结果转换为 hh:mi:ss强>。这是dbfiddle

IF OBJECT_ID('tempdb.dbo.#MyTable', 'U') IS NOT NULL
    DROP TABLE #MyTable;

CREATE TABLE #MyTable
(
    id INTEGER NOT NULL
  , date DATETIME NOT NULL
);
INSERT INTO #MyTable (id, date) VALUES (2380, '10/30/12 09:00:00');
INSERT INTO #MyTable (id, date) VALUES (2380, '10/30/12 09:05:00');
INSERT INTO #MyTable (id, date) VALUES (2380, '10/30/12 09:10:00');
INSERT INTO #MyTable (id, date) VALUES (2380, '10/30/12 09:15:00');
INSERT INTO #MyTable (id, date) VALUES (2381, '10/30/12 10:00:00');
INSERT INTO #MyTable (id, date) VALUES (2381, '10/30/12 10:05:00');
INSERT INTO #MyTable (id, date) VALUES (2381, '10/30/12 10:10:00');
INSERT INTO #MyTable (id, date) VALUES (2381, '10/30/12 10:15:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 11:00:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 11:05:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 10:10:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 10:15:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 12:15:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 10:15:30');

SELECT     a.*
         , CONVERT(NVARCHAR(8), a.date - b.ReferenceDate, 108) AS duration
FROM       #MyTable AS a
INNER JOIN (
    SELECT id, MIN(date) AS ReferenceDate 
    FROM #MyTable GROUP BY id) AS b ON a.id = b.id;

【讨论】:

  • 我没有测试过将我的新答案放在视图中,但没有 ORDER BY 我相信它应该可以工作。
  • 它确实有效,非常好,非常感谢。我想和你分享一张照片,所以我开始在推特上关注你。希望当你在那里接受我的请求时把你送到那里。祝你有美好的一天!
猜你喜欢
  • 2016-03-13
  • 1970-01-01
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
相关资源
最近更新 更多