0

有没有办法在没有自连接的情况下比较表的 2 行?

我有一个包含列的事件表:ID、日期、工具。我查询它,并将行号添加到结果集中(按日期排序,分别针对每个工具)。现在我想知道第 1 行和第 4 行之间的时间差是否超过一周。
我可以通过将我的查询连接到自身来实现这一点(非常简单),但是它会使查询运行两次(对吗?)这不是很有效(因为我的查询并不简单并且已经需要一些连接)。有没有更聪明的方法来实现这一目标?

我正在使用 SQL 服务器(不确定哪个版本;可能是 2008 年),并从 ASP.NET 应用程序进行查询,所以我没有对数据库的管理访问权限,并且一些高级的东西不起作用(但我愿意尝试每一个建议并检查)。谢谢。

4

1 回答 1

0

您可以使用窗口函数来实现您的目标,但也许 over(partition by ... order by) 就足够了(http://www.sqlfiddle.com/#!6/2d448/1):

IF OBJECT_ID('tempdb..#SomeTable', 'U') IS NOT NULL
BEGIN 
    DROP TABLE #SomeTable
END

create table #SomeTable (Id int, [date] datetime, tool nvarchar(80), description nvarchar(80))

DECLARE @date AS DATETIME

SET @date = CAST('2013-01-10' as datetime) 

declare @i as int = 0
declare @j as int = 0
declare @k as int = 0

WHILE (@i < 100)
begin
    set @i = @i + 1
    set @j = 0
    WHILE (@j < 100)
    begin
        set @j = @j + 1
        set @k = CAST(RAND() * 100 as int)      
        insert into #SomeTable (Id, [date], tool, description) values (@i*@j, DATEADD(dd,@k,@date), 'tool-' + STUFF('000', 3-LEN(@i)+1, LEN(@i), @i) , 'description-' + CAST(@i as nvarchar(10)) + '-' + CAST(@j as nvarchar(10)))
    end
end
--may be this will be enough
--select *, DATEDIFF(dd, MIN([date]) OVER(PARTITION BY tool), [date]) AS 'days' from #SomeTable order by tool, days
--sql 2012 only
--4 rows window
--select *, DATEDIFF(dd, MIN([date]) OVER(PARTITION BY tool ORDER BY tool, [date] ROWS BETWEEN 4 PRECEDING AND CURRENT ROW), [date]) AS 'days' from #SomeTable order by tool, days
select *, DATEDIFF(dd, MIN([date]) OVER(ORDER BY tool, [date] ROWS BETWEEN 4 PRECEDING AND CURRENT ROW), [date]) AS 'days' from #SomeTable order by tool, days
于 2013-10-01T11:25:16.927 回答