SQL如果打破数字模式,标记记录?

SQL如果打破数字模式,标记记录?,sql,sql-server-2005,Sql,Sql Server 2005,我有以下疑问: SELECT AccountNumber, RptPeriod FROM dbo.Report ORDER BY AccountNumber, RptPeriod. 我得到以下结果: 123 200801 123 200802 123 200803 234 200801 344 200801 344 200803 我需要为账户标记RPT期间不同时流动的记录。例如,3442000803旁边会有一个X,因为它从200801到200803 这是关于19321

我有以下疑问:

SELECT AccountNumber, RptPeriod
FROM dbo.Report
ORDER BY AccountNumber, RptPeriod.
我得到以下结果:

123   200801
123   200802
123   200803
234   200801
344   200801
344   200803
我需要为账户标记RPT期间不同时流动的记录。例如,3442000803旁边会有一个X,因为它从200801到200803

这是关于19321行的,我希望它以公司为基础,所以在不同的公司之间,我不关心数字是什么,我只希望同一家公司显示数字模式中的断点

有什么想法吗


谢谢

像这样的东西应该可以做到:

--  cte lists all items by AccountNumber and RptPeriod, assigning an ascending integer
--  to each RptPeriod and restarting at 1 for each new AccountNumber
;WITH cte (AccountNumber, RptPeriod, Ranking)
 as (select
        AccountNumber
       ,RptPeriod
       ,row_number() over (partition by AccountNumber order by AccountNumber, RptPeriod) Ranking
      from dbo.Report)
 --  and then we join each row with each preceding row based on that "Ranking" number
 select
    This.AccountNumber
   ,This.RptPeriod
   ,case
      when Prior.RptPeriod is null then ''  --  Catches the first row in a set
      when Prior.RptPeriod = This.RptPeriod - 1 then ''  --  Preceding row's RptPeriod is one less that This row's RptPeriod
      else 'x'  --  --  Preceding row's RptPeriod is not less that This row's RptPeriod
    end  UhOh
  from cte This
   left outer join cte Prior
    on Prior.AccountNumber = This.AccountNumber
     and Prior.Ranking = This.Ranking - 1

编辑以添加注释

好的,这是一种丑陋的双连接+反连接,但它完成了工作,并且是纯可移植SQL:

SELECT * 
FROM   dbo.Report R1
     , dbo.Report R2
WHERE  R1.AccountNumber = R2.AccountNumber
AND    R2.RptPeriod - R1.RptPeriod > 1
-- subsequent NOT EXISTS ensures that R1,R2 rows found are "next to each other",
-- e.g. no row exists between them in the ordering above
AND    NOT EXISTS
        (SELECT 1 FROM dbo.Report R3
        WHERE  R1.AccountNumber = R3.AccountNumber
        AND    R2.AccountNumber = R3.AccountNumber
        AND    R1.RptPeriod < R3.RptPeriod
        AND    R3.RptPeriod < R2.RptPeriod
        )

我不确定sql Server日期逻辑语法,但希望您能理解。r将是下一个RPT周期为空r2且至少存在一个更大的RPT周期r3的所有记录。我想查询不是非常直接的,但是如果你在两列上有索引,它可能是获取数据的最有效的方法。

基本上,你对每个帐户中的行进行编号,然后,使用行号,比较相邻行的rptpiriod值

这里假设RptPeriod是编码的年和月,在这种情况下,添加了年转换检查

;WITH Report_sorted AS (
  SELECT
    AccountNumber,
    RptPeriod,
    rownum = ROW_NUMBER() OVER (PARTITION BY AccountNumber ORDER BY RptPeriod)
  FROM dbo.Report
)
SELECT
  AccountNumber,
  RptPeriod,
  CASE ISNULL(CASE WHEN r1.RptPeriod / 100 < r2.RptPeriod / 100 THEN 12 ELSE 0 END
              + r1.RptPeriod - r2.RptPeriod, 1) AS Chk
    WHEN 1 THEN ''
    ELSE 'X' 
  END
FROM Report_sorted r1
  LEFT JOIN Report_sorted r2
    ON r1.AccountNumber = r2.AccountNumber AND r1.rownum = r2.rownum + 1

如果您需要的话,还需要额外检查一年或更长时间的缺口,这可能会更加复杂。

每个帐号、期间是否最多有一个匹配项?组合无重复一家公司只有一个报告期可以相同。我假设在第一个报告期中,R2.RptPeriod-R1.RptPeriod>1,在不存在的报告期中,R2.RptPeriod>R3.RptPeriod这似乎对OP的样本数据没有返回任何结果。@DVK-您的编辑仍然不起作用。它只返回一行。@Martin-原始数据中不是只有一个中断吗?@DVK-是。但据我所知,Philip的回答也是这样,OP希望所有行都返回,并用X标记该行。所以不确定是否需要在某个地方使用外部联接。。。
SELECT  *
FROM   report r
LEFT   JOIN report r2
ON     r.accountnumber = r.accountnumber
AND    {r2.rptperiod is one day after r.rptPeriod}
JOIN   report r3
ON     r3.accountNumber = r.accountNumber
AND    r3.rptperiod > r1.rptPeriod
WHERE  r2.rptPeriod IS NULL
AND    r3 IS NOT NULL
;WITH Report_sorted AS (
  SELECT
    AccountNumber,
    RptPeriod,
    rownum = ROW_NUMBER() OVER (PARTITION BY AccountNumber ORDER BY RptPeriod)
  FROM dbo.Report
)
SELECT
  AccountNumber,
  RptPeriod,
  CASE ISNULL(CASE WHEN r1.RptPeriod / 100 < r2.RptPeriod / 100 THEN 12 ELSE 0 END
              + r1.RptPeriod - r2.RptPeriod, 1) AS Chk
    WHEN 1 THEN ''
    ELSE 'X' 
  END
FROM Report_sorted r1
  LEFT JOIN Report_sorted r2
    ON r1.AccountNumber = r2.AccountNumber AND r1.rownum = r2.rownum + 1