我希望从每个部分的列表中获取缺少的协议编号 我有我的清单
ProtocolNumber Section
--------------------------------
14A1000014 | A1
14A1000015 | A1
14A1000018 | A1
14A1000019 | A1
14A2000014 | A2
14A2000015 | A2
14A2000019 | A2
我试试这个
SELECT lb1.ProtocolNumber, lb1.Section FROM #tmp lb1
WHERE not exists ( SELECT * FROM #tmp lb2
WHERE lb2.ProtocolNumber = lb1.ProtocolNumber + 1 and lb2.Section = lb1.Section)
输出应该是这样的
ProtocolNumber Section
--------------------------------
14A1000016 | A1
14A1000017 | A1
14A2000016 | A2
14A2000017 | A2
14A2000018 | A2
答案 0 :(得分:2)
假设您正在尝试生成该部分当前存在的最小和最大范围之间缺少协议编号的列表,我建议如下:
/*Sample Data*/
CREATE TABLE #tmp (ProtocolNumber VARCHAR(20), Section VARCHAR(2))
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A1000014', 'A1'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A1000015', 'A1'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A1000018', 'A1'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A1000019', 'A1'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A2000014', 'A2'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A2000015', 'A2'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A2000019', 'A2'
/*CTEs to generate numbers list: 1 through 1,000,000*/
;WITH
E1(N) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) s(N)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
E5(N) AS (SELECT 1 FROM E4 a, E2 b), --1,000,000 rows max
cteTally(N) AS ( SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E5 ),
/*CTE to identify ranges of current numbers for each Section*/
Ranges AS
(
SELECT
Section,
MIN(CAST(SUBSTRING(ProtocolNumber, 5,6) AS INT)) MinNumber,
MAX(CAST(SUBSTRING(ProtocolNumber, 5,6) AS INT)) MaxNumber
FROM
#tmp
GROUP BY Section
),
/*CTE to generate full list of available protocols for each Section*/
ProtocolList AS
(
SELECT DISTINCT
Section,
'14' + Section + RIGHT('00000' + CAST(N AS VARCHAR(6)),6) AS ProtocolNumber
FROM Ranges
INNER JOIN
cteTally ON
cteTally.N >= Ranges.MinNumber AND
cteTally.N <= Ranges.MaxNumber
)
/*Final SELECT - protocols in the master list that do not exist for those sections in the temp table*/
SELECT l.ProtocolNumber, l.Section
FROM
ProtocolList l
LEFT JOIN
#tmp t ON
l.ProtocolNumber = t.ProtocolNumber
WHERE t.ProtocolNumber IS NULL
ORDER BY
l.Section,
l.ProtocolNumber
DROP TABLE #tmp
答案 1 :(得分:0)
是否必须是一行选择陈述?
如何编写存储过程或表值函数,使用游标遍历表并创建缺失记录,函数返回
实施还需要检查每个给定部分的最大协议编号,以便您只创建范围内的记录
答案 2 :(得分:0)
遗失议定书清单
DECLARE @P INT=(SELECT COUNT(DISTINCT SECTION) FROM PROTOCOL) --NUMBER OF SECTION
DECLARE @w varchar(10)='A1' --HOLD TYPE OF SECTION
WHILE @P>0
BEGIN
DECLARE @q table(numx int) --HOLD MAX TO MIN ProtocolNumber
declare @i table(num int) --HOLD EXISTS 'ProtocolNumber'
INSERT INTO @i
select convert(int,right( ProtocolNumber,2)) FROM protocol WHERE Section=@w
DECLARE @x int=(select max(convert(int,right( ProtocolNumber,2))) FROM protocol WHERE Section=@w)
DECLARE @y int=(select min(convert(int,right( ProtocolNumber,2))) FROM protocol WHERE Section=@w)
WHILE @y <= @x
begin
INSERT INTO @q (numx)
VALUES(@y)
SET @y= @y + 1
END
SELECT ('14'+@w+'0000'+ convert(varchar(10),numx)) AS ProtocolNumber,@W AS Section
FROM @Q
where numx NOT IN (select * FROM @i)
SET @P=@P-1
SET @W='A2'
DELETE FROM @Q
DELETE FROM @I
END