在一次查询中查找文件名列表中缺失的数字
Find missing numbers in list of file names in one query
在文档管理数据库中有一个现有文件的列表。新文件应该有一个数字,例如 SW_01234.xxx。有一种为新号码服务的编号机制。问题是找到丢失的元素 - 例如文件是否被删除。
现有文件名可能完全不同并且不遵循上述方案。
我的尝试是这样做的:
在 "dot" 拆分现有文件 - 我不关心 .xxx 扩展名,例如 .doc、.xlsx
生成SW_00000到SW_99999的临时列表
引入b)中存在但a)中不存在的那些元素
样本值
..
SW_00015.PRT
SW_00016.DRW
SW_00020.DRW
SW_00020.PDF
XBC115.DOC
..
我需要得到 SW_00017、SW_00018、SW_00019(不关心 XBC)
最后需要一个查询
这应该让您完成了 99% 的事情。根据需要进行调整。您会注意到输出中缺少记录 1、3、4 和 10。
DECLARE @allFiles TABLE (Name VARCHAR(100));
DECLARE @i INT = 0;
DECLARE @dataset TABLE (name VARCHAR(100));
INSERT INTO @dataset
( name )
VALUES ( 'SW_00001.PRT'), ('SW_00003.DRW'), ('SW_00004.DRW'), ('SW_00010.PDF'
);
WHILE @i < 100
BEGIN
INSERT INTO @allFiles
( Name )
VALUES ( 'SW_' + REPLICATE('0',5-LEN(@i)) + CAST(@i AS VARCHAR(10)) -- Name - varchar(100)
);
SET @i = @i + 1;
END;
SELECT *
FROM @allFiles af
WHERE NOT EXISTS (SELECT TOP 1 1 FROM @dataset ds WHERE af.Name = SUBSTRING(ds.name, 0, CHARINDEX('.', ds.name)))
我试图在一个查询中实现您的所有方法。为了在一个查询中完成所有操作,我使用 CTE 来隔离文档编号,并获取要在 "not exists" 部分中使用的编号范围。如果您需要数字 table 中的更多范围,您可以通过不同的查询来获取范围。参见 Generate Sequential Set of Numbers
declare @t as table (DocName varchar(50));
insert @t (DocName)
values
('SW_00015.PRT')
,('SW_00016.DRW')
,('SW_00020.DRW')
,('SW_00020.PDF');
/*doing with CTE so the split and substring is more readable, plus needed it anyway for getting the numbers table*/
with isolatedFileNames
as (
/*might be dots in filename, reversing it to isolate the last set (file ext)*/
select DocName
,left(DocName, len(DocName) - charindex('.', reverse(DocName), 0)) as IsolatedDocName
from @t
)
,isolatedNumbers
as (
/*substring to get the number without the prefix*/
select DocName
,IsolatedDocName
,cast(substring(IsolatedDocName, charindex('_', IsolatedDocName, 0) + 1, len(IsolatedDocName)) as int) as IsolatedDocNumber
from isolatedFileNames
)
,numbers
as (
/*use row_number on a large set to get the range*/
select ROW_NUMBER() over (
order by object_id
) + (
/*start at the first document number, change this to 0 if you want to start at 0*/
select min(IsolatedDocNumber) - 1
from isolatedNumbers
) as num
from sys.all_objects
)
,numbersLessThanDocNumbers
as (
select num
from numbers
where num < (
/*limit to max document number in the set*/
select max(IsolatedDocNumber)
from isolatedNumbers
)
)
select num as MissingFromDocumentSet
from numbersLessThanDocNumbers n
where not exists (
select 1
from isolatedNumbers iso
where iso.IsolatedDocNumber = n.num
)
在文档管理数据库中有一个现有文件的列表。新文件应该有一个数字,例如 SW_01234.xxx。有一种为新号码服务的编号机制。问题是找到丢失的元素 - 例如文件是否被删除。
现有文件名可能完全不同并且不遵循上述方案。
我的尝试是这样做的:
在 "dot" 拆分现有文件 - 我不关心 .xxx 扩展名,例如 .doc、.xlsx
生成SW_00000到SW_99999的临时列表
引入b)中存在但a)中不存在的那些元素
样本值
..
SW_00015.PRT
SW_00016.DRW
SW_00020.DRW
SW_00020.PDF
XBC115.DOC
..
我需要得到 SW_00017、SW_00018、SW_00019(不关心 XBC)
最后需要一个查询
这应该让您完成了 99% 的事情。根据需要进行调整。您会注意到输出中缺少记录 1、3、4 和 10。
DECLARE @allFiles TABLE (Name VARCHAR(100));
DECLARE @i INT = 0;
DECLARE @dataset TABLE (name VARCHAR(100));
INSERT INTO @dataset
( name )
VALUES ( 'SW_00001.PRT'), ('SW_00003.DRW'), ('SW_00004.DRW'), ('SW_00010.PDF'
);
WHILE @i < 100
BEGIN
INSERT INTO @allFiles
( Name )
VALUES ( 'SW_' + REPLICATE('0',5-LEN(@i)) + CAST(@i AS VARCHAR(10)) -- Name - varchar(100)
);
SET @i = @i + 1;
END;
SELECT *
FROM @allFiles af
WHERE NOT EXISTS (SELECT TOP 1 1 FROM @dataset ds WHERE af.Name = SUBSTRING(ds.name, 0, CHARINDEX('.', ds.name)))
我试图在一个查询中实现您的所有方法。为了在一个查询中完成所有操作,我使用 CTE 来隔离文档编号,并获取要在 "not exists" 部分中使用的编号范围。如果您需要数字 table 中的更多范围,您可以通过不同的查询来获取范围。参见 Generate Sequential Set of Numbers
declare @t as table (DocName varchar(50));
insert @t (DocName)
values
('SW_00015.PRT')
,('SW_00016.DRW')
,('SW_00020.DRW')
,('SW_00020.PDF');
/*doing with CTE so the split and substring is more readable, plus needed it anyway for getting the numbers table*/
with isolatedFileNames
as (
/*might be dots in filename, reversing it to isolate the last set (file ext)*/
select DocName
,left(DocName, len(DocName) - charindex('.', reverse(DocName), 0)) as IsolatedDocName
from @t
)
,isolatedNumbers
as (
/*substring to get the number without the prefix*/
select DocName
,IsolatedDocName
,cast(substring(IsolatedDocName, charindex('_', IsolatedDocName, 0) + 1, len(IsolatedDocName)) as int) as IsolatedDocNumber
from isolatedFileNames
)
,numbers
as (
/*use row_number on a large set to get the range*/
select ROW_NUMBER() over (
order by object_id
) + (
/*start at the first document number, change this to 0 if you want to start at 0*/
select min(IsolatedDocNumber) - 1
from isolatedNumbers
) as num
from sys.all_objects
)
,numbersLessThanDocNumbers
as (
select num
from numbers
where num < (
/*limit to max document number in the set*/
select max(IsolatedDocNumber)
from isolatedNumbers
)
)
select num as MissingFromDocumentSet
from numbersLessThanDocNumbers n
where not exists (
select 1
from isolatedNumbers iso
where iso.IsolatedDocNumber = n.num
)