【问题标题】:T-SQL Identifying gaps in broken sequence of datesT-SQL 识别损坏的日期序列中的间隙
【发布时间】:2018-11-16 17:27:28
【问题描述】:

请您帮忙解决我遇到的问题,我认为这与 T-SQL 中的间隙和孤岛问题有关。我正在使用 SQL Server 2014。

我正在尝试使用日期列来识别表/索引组合的连续出现次数,以区分损坏的链。

请参阅下面的 T-SQL 来演示我想要实现的目标,特别是如何计算出于演示目的我手动硬编码的 Rnk 列?

CREATE TABLE #test (RowID INT IDENTITY(1,1), FileDate DATE, TableName VARCHAR(100), IndexName VARCHAR(100), Rnk INT)

INSERT INTO #test (FileDate, TableName, IndexName, Rnk) 
VALUES
('2015-10-31', 't1', 'idx1', 1),
('2015-10-30', 't1', 'idx1', 2),

('2015-10-27', 't1', 'idx1', 1),
('2015-10-26', 't1', 'idx1', 2),
('2015-10-25', 't1', 'idx1', 3),

('2015-10-23', 't1', 'idx1', 1),
('2015-10-22', 't1', 'idx1', 2),
('2015-10-21', 't1', 'idx1', 3),
('2015-10-20', 't1', 'idx1', 4),
('2015-10-19', 't1', 'idx1', 5),
('2015-10-15', 't1', 'idx1', 1),
('2015-10-13', 't1', 'idx1', 1),
('2015-10-10', 't1', 'idx1', 1),
('2015-10-09', 't1', 'idx1', 2),

('2015-10-27', 't3', 'idx13', 1),
('2015-10-26', 't3', 'idx13', 2),
('2015-10-25', 't3', 'idx15', 1),
('2015-10-24', 't3', 'idx15', 2),
('2015-10-21', 't3', 'idx13', 1)

SELECT * FROM #test 

DROP TABLE #test

在我附加的屏幕截图中,突出显示的结果部分将显示我希望 Rnk 列对 2015 年 10 月 27 日至 2015 年 10 月 25 年间 t1/idx 的连续出现进行排序,但重置数字下一次出现在 2015-10-23 到 2015-10-19。

谁能帮帮我?

谢谢。

【问题讨论】:

    标签: sql-server tsql sequence gaps-and-islands


    【解决方案1】:

    从日期中减去一系列数字 - 您已识别的组将具有恒定值。然后你可以使用row_number():

    select t.*,
           row_number() over (partition by tablename, indexname,
                                           dateadd(day, - seqnum, filedate)
                              order by filedate desc
                             ) as rnk
    from (select t.*,
                 row_number() over (partition by tablename, indexname order by filedate) as seqnum
          from t
         ) t
    

    【讨论】:

      【解决方案2】:

      我会使用累积方法:

      select t.FileDate, t.TableName, t.IndexName,
             row_number() over (partition by tablename, indexname, grp order by rowid)
      from (select t.*, sum(case when gap > 1 then 1 else 0 end) over (partition by tablename, indexname order by rowid) as grp
            from (select t.*, 
                         isnull(datediff(day, filedate, lag(filedate) over (partition by tablename, indexname order by rowid)), 1) as gap
                  from #test t
                 ) t
           ) t;
      

      【讨论】:

      • 谢谢,等我回到办公室试试这个方法。
      【解决方案3】:

      与 Yogesh 的回答类似,他击败了我。
      (提示:不要指望在手机上输入答案时会更快)

      SELECT 
      RowID, FileDate, TableName, IndexName, 
      ROW_NUMBER() OVER (PARTITION BY TableName, IndexName,  DateRank ORDER BY FileDate DESC) AS Rnk
      FROM
      (
        SELECT *,
        SUM(DateGap) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC) AS DateRank
        FROM
        (
            SELECT RowID, FileDate, TableName, IndexName,
            --  Rnk as ExpRnk,
            CASE WHEN DATEDIFF(DAY, FileDate, LAG(FileDate) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC)) <= 1 THEN 0 ELSE 1 END AS DateGap
            FROM #Test
        ) q1
      ) q2
      ORDER BY RowID;
      

      【讨论】:

        猜你喜欢
        • 2021-07-12
        • 2021-08-03
        • 1970-01-01
        • 2014-12-30
        • 1970-01-01
        • 1970-01-01
        • 2021-01-27
        • 2013-03-03
        • 2019-02-06
        相关资源
        最近更新 更多