【问题标题】:Checking next row in table is incremented by 1 minute in datetime column检查表中的下一行在 datetime 列中增加 1 分钟
【发布时间】:2013-05-12 05:43:38
【问题描述】:

我需要检查表格中的大量数据,以确保我的提要没有跳过任何内容。

基本上表格有以下列

ID 日期时间价格

DateTime 列中的数据在每个连续行中增加 1 分钟。我需要检查当前行的下一行,看看是否比该特定上下文中正在查询的行高 1 分钟。

查询可能需要某种循环,然后获取下一行的副本并将其与当前行的日期时间行进行比较,以确保它增加了 1 分钟。

【问题讨论】:

    标签: sql-server sql-server-2008


    【解决方案1】:

    我创建了一个测试表来匹配您的描述,并在每行之间插入 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 查找应该在下一分钟找到的记录。表格的最后一条记录当然会报告下一行丢失,因为它还没有被插入。

    【讨论】:

    • 这确实找到了我数据中的空白,但是有一点是它显示了空白之后的行,所以“下一条记录丢失”应该是“最后一行被跳过”之类的。这可能是因为您的测试表将时间从第 1 行的最近时间增加到第 100 行的过去时间,而我的实际数据在第 1 行具有最早的时间。无论如何,这确实有助于我看到差距和功能是我需要做的。谢谢!
    【解决方案2】:

    借用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 
    

    【讨论】:

    • 我在我的数据上试过这个,我使用的是 SQL Server 2008 Express R2。我得到:消息 252,级别 16,状态 1,行 1 递归公用表表达式“测试”不包含顶级 UNION ALL 运算符。
    • +1 不错的解决方案,最少。逻辑读取(源表只读取一次)。
    • @magister - 如果您将 CTE 重命名为 Test,则会收到该错误。它必须被赋予与源表不同的名称。在我的回答中,CTE 名为T,源表为Test。我的答案中的代码确实 not 给出了该错误。 SQL Fiddle
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多