SQL 服务器根据 case when 的结果向计数器加 1

SQL Server add 1 to counter based on result of case when

谁能告诉我我添加的代码是否有效? 它给我语法错误,我不知道为什么。

问题 票号是连续的,但偶尔会有几百万号的大突破。服务器无法将所有几百万行计算为丢失,因此我想在代码进入下一个游标之前设置一个限制,比如 50 行丢失。

样本数据集

添加了更多代码以给出问题的上下文。

DECLARE DB_CURSOR CURSOR FOR 

SELECT PCC
FROM 
#PCC_TEMP


OPEN DB_CURSOR
FETCH NEXT FROM DB_CURSOR INTO
@NAME

WHILE @@FETCH_STATUS = 0

BEGIN

;WITH Missing (missnum, maxid)
AS
(
 SELECT (select min(Ticket_no) from #Temp where PCC = @name) AS missnum, (select max(Ticket_no) from #Temp where PCC = @name)
 UNION ALL
 SELECT missnum + 1, maxid FROM Missing
 WHERE missnum < maxid

)

SELECT missnum as [Ticket],
case when(tt.Ticket_no is NULL) then '' else tt.routing_info END as [Routing],
case when(tt.Ticket_no is NULL) then '' else tt.trip END as [Trip],
case when(tt.Ticket_no is NULL) then '' else tt.PNR END as [PNR],
case when(tt.Ticket_no is NULL) then '' else tt.PCC END as [PCC],
case when(tt.Ticket_no is NULL) then 'Missing' else 'Present' END as [Status],
case when(tt.Ticket_no is NULL) then     SET @Missing_Counter = @Missing_Counter +1 END

FROM Missing
LEFT OUTER JOIN #Temp tt on tt.Ticket_no = Missing.missnum
OPTION (MAXRECURSION 0); 


FETCH NEXT FROM DB_CURSOR INTO
@NAME

END

CLOSE DB_CURSOR

DEALLOCATE DB_CURSOR

DROP TABLE #Temp

DROP TABLE #PCC_TEMP

干杯

戴夫

您真正想要的是统计空票号,那为什么不统计空票号呢?

SELECT @Missing_Counter = COUNT(1) 
FROM {Table}
WHERE Ticket_no is NULL

2008之后的SQL服务器,可以直接使用lag()lead()。你可以这样做:

select (ticket_number + 1) as first_missing,
       (next_ticket_number - 1) as last_missing,
       (next_ticket_number - ticket_number - 1) as num_missing
from (select t.*, lead(ticket_number) over (order by ticket_number) as next_ticket_number
      from #Temp t
     ) t
where next_ticket_number <> ticket_number + 1;

忘记你的语法错误。无论如何,代码可能真的很低效。另外,我不明白你为什么要为此使用游标。尽可能使用基于集合的方法。

在早期版本中,您可以这样做:

select (ticket_number + 1) as first_missing,
       (next_ticket_number - 1) as last_missing,
       (next_ticket_number - ticket_number - 1) as num_missing
from (select t.*, t2.ticket_number as next_ticket_number
      from #Temp t cross apply
           (select top (1) t2.ticket_number
            from #temp t2
            where t2.ticket_number > t.ticket_number
            order by t2.ticket_number asc
           ) t2
     ) t
where next_ticket_number <> ticket_number + 1;

虽然效率不如lead(),但可以利用ticket_number()上的索引。