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()
上的索引。
谁能告诉我我添加的代码是否有效? 它给我语法错误,我不知道为什么。
问题 票号是连续的,但偶尔会有几百万号的大突破。服务器无法将所有几百万行计算为丢失,因此我想在代码进入下一个游标之前设置一个限制,比如 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()
上的索引。