SQL Server 根据 case 的结果将计数器加 1 时
Posted
技术标签:
【中文标题】SQL Server 根据 case 的结果将计数器加 1 时【英文标题】:SQL Server add 1 to counter based on result of case when 【发布时间】:2018-02-01 21:48:48 【问题描述】:谁能告诉我我添加的代码是否可以工作? 它给了我语法错误,我不知道为什么。
问题 票号是连续的,但偶尔会有几百万个数字的大突破。服务器无法将所有几百万行计算为丢失,因此我想在代码进入下一个游标之前设置一个 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
干杯
戴夫
【问题讨论】:
你能提供更多你的 SQL 吗? 添加了更多代码,谢谢 你的问题是你试图在你的选择中设置。 看起来这是递归 cte 中的最终选择,你能发布整个 cte 吗?另外,丢失计数器的最终目标是什么(您需要运行总数还是总数)? 感谢您的更新。我认为最能帮助人们的是添加一些示例模式/数据和所需的结果。我相信您只需要 recursive-cte (首选,作为基于集合的方法)或游标,而不是两者。您还可以用您使用的 SQL Server 版本(08/12/14/16/等)标记问题吗? 【参考方案1】:在 2008 年以后的 SQL Server 中,您可以只使用 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()
上的索引。
【讨论】:
我正在使用 2008 R2,但遗憾的是,我不确定 Lag 和 Lead 是否适合我。【参考方案2】:你真正想要的是计算空票号,那么为什么不计算空票号呢?
SELECT @Missing_Counter = COUNT(1)
FROM Table
WHERE Ticket_no is NULL
【讨论】:
我可以连续有 300 万个空值,但过程太繁重了。我想设置 50 个空值的限制,然后跳到下一步。以上是关于SQL Server 根据 case 的结果将计数器加 1 时的主要内容,如果未能解决你的问题,请参考以下文章