下面是我的表结构
MyTable
-----------
ObjectID int (Identity), -- Primary Key
FileName varchar(10),
CreatedDate datetime
...........
...........
...........我需要获取在文件中创建记录所用的时间...即..。同一文件中的前一条记录与同一文件的当前记录之间经过的时间
即..。如果记录是
ObjectID FileName CreatedDate (just showing the time part here)
-------- -------- -----------
1 ABC 10:23
2 ABC 10:25
3 DEF 10:26
4 ABC 10:30
5 DEF 10:31
6 DEF 10:35所需的输出为...
ObjectID FileName CreatedDate PrevRowCreatedDate
-------- -------- ----------- ---------------
1 ABC 10:23 NULL
2 ABC 10:25 10:23
3 DEF 10:26 NULL
4 ABC 10:30 10:25
5 DEF 10:31 10:26
6 DEF 10:35 10:31到目前为止,我收到了这个查询,但它花费的时间比预期的要长……有没有更好的方法...
Select A.ObjectID,
A.FileName
A.CreatedDate as CreatedDate,
B.PrevRowCreatedDate,
datediff("SS", '1900-01-01 00:00:00', Coalesce((A.CreatedDate - B.PrevRowCreatedDate),0)) as secondsTaken
from MyTable as A
Cross Apply (
(Select PrevRowCreatedDate = Max(CreatedDate) from MyTable as BB
where BB.FileName = A.FileName and
BB.CreatedDate < A.CreatedDate
)
) as B 如果你需要更多信息,请让我知道
谢谢
发布于 2010-08-06 22:28:01
SELECT t1.FileName, t1.CreatedDate, t2.CreatedDate as PrevCreatedDate
FROM
(SELECT FileName, CreateDate,
ROW_NUMBER() OVER(PARTITION BY FileName ORDER BY CreatedDate) AS OrderNo
FROM MyTable) t1
LEFT JOIN
(SELECT FileName, CreateDate,
ROW_NUMBER() OVER(PARTITION BY FileName ORDER BY CreatedDate) AS OrderNo
FROM MyTable) t2
ON (t1.FileName = t2.FileName AND t1.OrderNo = t2.OrderNo - 1)或者更好地使用'WITH',因为查询是相同的:
WITH t(ObjectID, FileName, CreatedDate, OrderNo) AS
(SELECT ObjectID, FileName, CreatedDate,
ROW_NUMBER() OVER(PARTITION BY FileName ORDER BY CreatedDate) AS OrderNo
FROM MyTable)
SELECT t1.ObjectID, t1.FileName, t1.CreatedDate, t2.CreatedDate AS PrevCreatedDate,
DATEDIFF("SS", '1900-01-01 00:00:00',
COALESCE((t1.CreatedDate - t2.CreatedDate),0)) AS secondsTaken
FROM t t1 LEFT JOIN t t2
ON (t1.FileName = t2.FileName AND t1.OrderNo = t2.OrderNo + 1)发布于 2010-08-07 01:50:26
我认为Michael的答案确实应该被证明更有效率。但是,在评估效率时,我只想引起人们注意Management Studio中显示的查询成本(相对于批处理)的一个问题。
我建立了一个有23,174行的测试表,并运行了问题中的查询和Michael的查询。查看实际执行计划中的“查询成本(相对于批处理)”,原始查询是1%,Michael的99%的成本,因此看起来效率非常低。

然而,实际的统计数据告诉我们一个完全不同的故事。
交叉应用方法
SQL Server执行时间: CPU时间=0毫秒,运行时间=0毫秒。
表'MyTable‘。扫描计数23175、逻辑读取49335、物理读取0、预读0、lob逻辑读取0、lob物理读取0、lob预读读取0。
ROW_NUMBER方法
CPU执行时间:
时间=391ms,运行时间=417ms。
表'Worktable‘。扫描计数为0、逻辑读取为0、物理读取为0、预读为0、lob逻辑读取为0、lob物理读取为0、lob预读为0。
表'MyTable‘。扫描计数2、逻辑读取148、物理读取0、预读读取0、lob逻辑读取0、lob物理读取0、lob预读读取0。
在ROW_NUMBER计划中,rownumber=rownumber+1上的合并连接两边都有23,174行。这个值是唯一的,实际输出的行数也是23,174。但是,SQL Server估计该连接产生的行数将为34,812,000,因此它对计划中稍后插入操作的估计成本是非常不准确的。
测试脚本
BEGIN TRAN
CREATE TABLE MyTable
(
[ObjectID] [INT] IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
[FileName] [VARCHAR](50) NULL,
[CreatedDate] [DATETIME] NULL
)
GO
INSERT INTO MyTable
SELECT ISNULL(type, NEWID()),
DATEADD(DAY, CAST(RAND(CAST(NEWID() AS VARBINARY)) * 10000 AS INT), GETDATE())
FROM master.dbo.spt_values,
(SELECT TOP 10 1 AS X FROM master.dbo.spt_values) V
DELETE FROM MyTable
WHERE EXISTS(SELECT *
FROM MyTable m2
WHERE MyTable.CreatedDate = m2.CreatedDate
AND MyTable.FileName = m2.FileName
AND MyTable.ObjectID < m2.ObjectID)
CREATE UNIQUE NONCLUSTERED INDEX [IX_MyTable]
ON MyTable ([FileName] ASC, [CreatedDate] ASC)
SET STATISTICS IO ON
SET STATISTICS TIME ON
SELECT A.ObjectID,
A.FileName,
A.CreatedDate AS CreatedDate,
B.PrevRowCreatedDate,
DATEDIFF("SS", '1900-01-01 00:00:00', COALESCE(( A.CreatedDate - B.PrevRowCreatedDate ), 0)) AS secondsTaken
INTO #A
FROM MyTable AS A
CROSS APPLY ((SELECT PrevRowCreatedDate = MAX(CreatedDate)
FROM MyTable AS BB
WHERE BB.FileName = A.FileName
AND BB.CreatedDate < A.CreatedDate)) AS B;
WITH t(ObjectID, FileName, CreatedDate, OrderNo)
AS (SELECT ObjectID,
FileName,
CreatedDate,
RANK() OVER(PARTITION BY FileName ORDER BY CreatedDate) AS OrderNo
FROM MyTable)
SELECT t1.ObjectID,
t1.FileName,
t1.CreatedDate,
t2.CreatedDate AS PrevCreatedDate,
DATEDIFF("SS", '1900-01-01 00:00:00', COALESCE(( t1.CreatedDate - t2.CreatedDate ), 0)) AS secondsTaken
INTO #B
FROM t t1
LEFT JOIN t t2
ON ( t1.FileName = t2.FileName
AND t1.OrderNo = t2.OrderNo + 1 )
/*Test the 2 queries give the same result*/
SELECT *
FROM #A
EXCEPT
SELECT *
FROM #B
SELECT *
FROM #B
EXCEPT
SELECT *
FROM #A
ROLLBACK https://stackoverflow.com/questions/3424650
复制相似问题