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