【发布时间】:2013-05-12 05:43:38
【问题描述】:
我需要检查表格中的大量数据,以确保我的提要没有跳过任何内容。
基本上表格有以下列
ID 日期时间价格
DateTime 列中的数据在每个连续行中增加 1 分钟。我需要检查当前行的下一行,看看是否比该特定上下文中正在查询的行高 1 分钟。
查询可能需要某种循环,然后获取下一行的副本并将其与当前行的日期时间行进行比较,以确保它增加了 1 分钟。
【问题讨论】:
标签: sql-server sql-server-2008
我需要检查表格中的大量数据,以确保我的提要没有跳过任何内容。
基本上表格有以下列
ID 日期时间价格
DateTime 列中的数据在每个连续行中增加 1 分钟。我需要检查当前行的下一行,看看是否比该特定上下文中正在查询的行高 1 分钟。
查询可能需要某种循环,然后获取下一行的副本并将其与当前行的日期时间行进行比较,以确保它增加了 1 分钟。
【问题讨论】:
标签: sql-server sql-server-2008
我创建了一个测试表来匹配您的描述,并在每行之间插入 100 行,如下所示:
CREATE TABLE [Test] ([Id] int IDENTITY(1,1), [Date] datetime, [Price] int);
WITH [Tally] AS (
SELECT GETDATE() AS [Date]
UNION ALL
SELECT DATEADD(minute, -1, [Date]) FROM [Tally] WHERE [Date] > DATEADD(minute, -99, GETDATE())
)
INSERT INTO [Test] ([Date], [Price])
SELECT [Date], 123 AS [Price]
FROM [Tally]
然后我删除了中间的一条记录来模拟丢失的一分钟:
DELETE FROM [Test]
WHERE Id = 50
现在我们可以使用这个查询来查找丢失的记录:
SELECT
a.*
,CASE WHEN b.[Id] IS NULL THEN 'Next record is Missing!' ELSE CAST(b.[Id] as varchar) END AS NextId
FROM
[Test] AS a
LEFT JOIN [Test] AS b ON a.[Date] = DATEADD(minute,1,b.[Date])
WHERE
b.[Id] IS NULL
结果将如下所示:
Id Date Price NextId
----------- ----------------------- ----------- ------------------------------
49 2013-05-11 22:42:56.440 123 Next record is Missing!
100 2013-05-11 21:51:56.440 123 Next record is Missing!
(2 row(s) affected)
解决问题的关键是将表与自身连接起来,但使用 datediff 查找应该在下一分钟找到的记录。表格的最后一条记录当然会报告下一行丢失,因为它还没有被插入。
【讨论】:
借用TheQ的样本数据你可以使用
WITH T
AS (SELECT *,
DATEDIFF(MINUTE, '20000101', [Date]) -
DENSE_RANK() OVER (ORDER BY [Date]) AS G
FROM Test)
SELECT MIN([Date]) AS StartIsland,
MAX([Date]) AS EndIsland
FROM T
GROUP BY G
【讨论】:
Test,则会收到该错误。它必须被赋予与源表不同的名称。在我的回答中,CTE 名为T,源表为Test。我的答案中的代码确实 not 给出了该错误。 SQL Fiddle