不同行的两个字段之间的差异

时间:2015-04-16 14:13:27

标签: sql oracle

让我们说这是我的选择查询的结果:

ID    Name    Status    Edit    Date
1     n1      closed    edt1      01/01/2005
1     n1      closed    edt2      15/01/2005
1     n1      closed    edt3      20/01/2005

我试图做的是获取edit1的日期和edit2的日期(编辑花了多少天)之间的差异并将其放在单独的列上。

请记住,我得到了一个结果(用于测试目的),如下所示:

select x.id, x.name, x.status, y.edit, y.date
from (table1 x left join table2 y on x.id = y.id)
where x.id = 1 

那么我怎样才能获得每次编辑之间花费的天数并将其放在一个已删除的列上?当然不再是where x.id = 1 ......我的查询结果应该是这样的:

id    name    status    edit_1(edt2 - edt1)   edit_2(edt3 - edt2)   
1     n1      closed    14                    5

感谢您帮助^^

3 个答案:

答案 0 :(得分:0)

您可以使用LEAD()分析函数:

SELECT id, name, status, edit, date, LEAD(date) OVER ( PARTITION BY id ORDER BY date ) - date AS edit_diff
  FROM mytable;

如果要将一定数量的编辑内容放入自己的列中,则可以PIVOT从上面的查询返回的日期;如果#编辑是任意的,那么你需要使用PL / SQL来完成它。

请注意,我假设namestatus不会因id而异;如果您想跟踪对这些内容的修改,那么您需要将这些列添加到LEAD()分区。


假设您将始终拥有固定数量的日期(让我们假设您的示例中有三个日期,给出两个日期差异),您可以使用条件聚合进行转动。我们将上面的查询用作公用表表达式(CTE);你也可以将它用作子查询,如果这更符合你的风格。我觉得这种方式比较干净。我打算给ROW_NUMBER()添加一个电话:

WITH mydata AS (
    SELECT id, name, status, edit, date
         , LEAD(date) OVER ( PARTITION BY id ORDER BY date ) - date AS edit_diff
         , ROW_NUMBER() OVER ( PARTITION BY id ORDER BY date ) AS rn
      FROM mytable
)
SELECT id, name, status, edit, date
     , MAX(CASE WHEN rn = 1 THEN edit_diff END) AS edit_1
     , MAX(CASE WHEN rn = 2 THEN edit_diff END) AS edit_2
  FROM mydata
 GROUP BY id, name, status, edit, date;

(顺便说一句,date不是列的好名字。我假设这只是一个例子而不是实际名称。)

答案 1 :(得分:0)

我会添加一个递增的id列,如下所示:http://www.orafaq.com/wiki/AutoNumber_and_Identity_columns然后按如下方式编写查询:

select x.id, x.name, x.status, y.edit, y.date, y.date - z.date
from (table1 x left join table2 y on x.id = y.id left join table2 z on y.newid = z.newid - 1)
where x.id = 1

答案 2 :(得分:-1)

CREATE TABLE [dbo].[EditTry]
(
[ID] [int] NULL,
[Name] [varchar](50) NULL,
[Status] [varchar](50) NULL,
[Edit] [varchar](50) NULL,
[Date] [datetime] NULL
) 

INSERT [dbo].[EditTry] ([ID], [Name], [Status], [Edit], [Date]) VALUES (1, N'n1', N'closed', N'edt1', '2005-01-01')
INSERT [dbo].[EditTry] ([ID], [Name], [Status], [Edit], [Date]) VALUES (1, N'n1', N'closed', N'edt2', '2005-01-15')
INSERT [dbo].[EditTry] ([ID], [Name], [Status], [Edit], [Date]) VALUES (1, N'n1', N'closed', N'edt3', '2005-01-20')


with tempss as
(
SELECT ID,Edit,[Date],RANK() OVER (ORDER BY Edit) AS Rank FROM EditTry 
)

select t1.*,datediff(dd,t1.date,(select top 1 date from tempss t2 where t2.id = t1.id and t1.rank < t2.rank)) as Dif from tempss t1 

在SQL Server中工作