Sql server 查找varchar变量中最后一个数值的序列
我在一个表中有一列,它的值递增,如:Sql server 查找varchar变量中最后一个数值的序列,sql-server,Sql Server,我在一个表中有一列,它的值递增,如: AAA0000001 AAA0000002 。。。等等 我想知道此列中存储的值是否按正确的顺序排列,或者中间是否缺少任何值,或者是否删除了任何值 如何实现这一点?假设模式始终为:AAA[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9],您可以通过理货表来实现 样本数据: CREATE TABLE Tbl(val VARCHAR(10)) INSERT INTO Tbl VALUES ('AAA0000001'), ('AAA
AAA0000001
AAA0000002
。。。等等
我想知道此列中存储的值是否按正确的顺序排列,或者中间是否缺少任何值,或者是否删除了任何值
如何实现这一点?假设模式始终为:
AAA[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
,您可以通过理货表来实现
样本数据:
CREATE TABLE Tbl(val VARCHAR(10))
INSERT INTO Tbl VALUES
('AAA0000001'), ('AAA0000002'), ('AAA0000004'), ('AAA0000011');
val
----------
AAA0000001
AAA0000002
AAA0000004
AAA0000011
结果
N val
-------------------- ----------
3 AAA0000003
5 AAA0000005
6 AAA0000006
7 AAA0000007
8 AAA0000008
9 AAA0000009
10 AAA0000010
说明:
CTE
的CTE
提取字符串的数字部分,并将其转换为INT
CTE
s,从E1
到Tally(N)
生成一个表,其中包含从1
到MAX(num)
的顺序值-从第一个CTE
返回的INT
SELECT
只检查第一个CTE
中不存在的num
'AAA'+RIGHT('0000000'+CAST(N为VARCHAR(7)),7)
转换N
以使其遵循该模式这是一个缺口问题。您可以查看Dwain Camps的这篇文章,以了解更多有关的解决方案 您可以像这样使用
行号
样本数据
DECLARE @tab1 TABLE(id VARCHAR(20));
insert into @tab1 VALUES('AAA0000001'),('AAA0000002'),('AAA0000003'),('AAA0000004'),('AAA0000006'),('AAA0000007'),('AAA0000010');
查询
;WITH CTE as
(
SELECT convert(int,STUFF(id,1,3,'')) id,convert(int,STUFF(id,1,3,'')) - ROW_NUMBER()OVER(ORDER BY convert(int,STUFF(id,1,3,''))) rn
FROM @tab1
),CTE2 as
(
SELECT ROW_NUMBER()OVER(ORDER BY rn) as rn, MIN(id) series_start,MAX(id) series_end
FROM CTE
GROUP BY rn
)
SELECT C2.series_end,C1.series_start
FROM CTE2 C1
INNER JOIN CTE2 C2 ON C1.rn = C2.rn + 1;
解释
- CTE的输出是id值之间的间隙差
- CTE2的输出是连续数列的开始和结束
- 最终输出给出系列中间隙的开始和结束
series_end series_start
4 6
7 10
如果模式是固定的,那么就不需要复杂的查询。这项工作:
DECLARE @t TABLE ( v VARCHAR(100) );
INSERT INTO @t
VALUES ( 'AAA0000001' ),
( 'AAA0000002' ),
( 'AAA0000007' ),
( 'AAA0000008' ),
( 'AAA0000010' ),
( 'AAA0000011' ),
( 'AAA0000012' );
SELECT * FROM @t t1
CROSS APPLY(SELECT TOP 1 v FROM @t t2 WHERE t2.v > t1.v ORDER BY v) ca
WHERE RIGHT(t1.v, 7) <> RIGHT(ca.v, 7) - 1
在SQLServer2012中,可以使用和 结果:
previous_exists next_exists col1
No Yes AAA0000001
Yes No AAA0000002
No No AAA0000004
您期望的结果/预期的输出是什么?输出中应显示缺少的ID您是否有类似
'aab000001'
,'aab000002'
的记录?这些值是否具有一致的模式?10个字符,其中前3个是字母,后7个是数字。是的,前三个字符总是相同的,后7个是数字。没问题,很高兴我能帮上忙。
v v
AAA0000002 AAA0000007
AAA0000008 AAA0000010
DECLARE @t table(col1 varchar(15))
INSERT @t values('AAA0000001'),('AAA0000002'),('AAA0000004')
SELECT
case when
stuff(lag(col1) over (order by col1), 1,3,'') + 1
= stuff(col1, 1,3,'') then 'Yes' else 'No' end previous_exists,
case when
stuff(lead(col1) over (order by col1), 1,3,'') - 1
= stuff(col1, 1,3,'') then 'Yes' else 'No' end next_exists,
col1
FROM @t
previous_exists next_exists col1
No Yes AAA0000001
Yes No AAA0000002
No No AAA0000004