在T-SQL中使用游标 - 将结果的最后一行中的列留空

时间:2017-05-30 15:45:32

标签: sql sql-server

快速提问,

所以我创建了一个我在医疗数据库上使用的游标,它将在一行显示特定遭遇(凭证)的所有帐单代码(CPT代码)。这样的原因是遇到可以有许多帐单代码,并且遇到>计费代码表关系是一对多的。因此,如果遭遇有3个帐单代码,则结果集中将有3行,每个代码一行。

让我们举例说,我有:     

    Voucher_Number          CPT 
1 A
1 B
1 C
2 Z
2 X
2 Y
3 P
3 Q
3 S
    我目前使用的代码最终会得到以下结果:
    

Voucher_Number CPT

1 A, B, C
2 Z, X, Y,
3 NULL

这是我目前正在使用的光标,临时表#VoucherData为Voucher_Number和CPT的每个唯一组合都有一行

我确信这是一件非常简单的事情,我在这里失踪了,这段代码是在他们离开之前由其他人给我的,他说他从不打扰修复它,最后一行只是手动查找代码(这不是我们只是将结果转储到Excel文件中的应用程序的一部分)

/* Cursor FOR CPT CODES */

DECLARE @CPTTABLE TABLE (voucher_number INT , cptcode varchar(255))
DECLARE @CPT varchar(max)
DECLARE @CPTCODE varchar(50)
DECLARE @CPTVOUCHER INT
DECLARE @CURRENTCPTVOUCHER INT
DECLARE CPTCURSOR CURSOR FOR SELECT DISTINCT Voucher_Number, CPT FROM #VoucherData ORDER BY Voucher_Number, CPT

OPEN CPTCURSOR
FETCH NEXT FROM CPTCURSOR INTO @CPTVOUCHER, @CPTCODE
SET @CURRENTCPTVOUCHER=@CPTVOUCHER
WHILE @@FETCH_STATUS=0
BEGIN 
  IF @CURRENTCPTVOUCHER<>@CPTVOUCHER
  BEGIN
    INSERT INTO @CPTTABLE VALUES(@CURRENTCPTVOUCHER, @CPT) 
    SET @CPT=NULL 
    SET @CURRENTCPTVOUCHER=@CPTVOUCHER 
  END 

  SET @CPT = ISNULL(@CPT+', ',' ')+@CPTCODE 
  FETCH NEXT FROM CPTCURSOR INTO @CPTVOUCHER, @CPTCODE  
END 
CLOSE CPTCURSOR 
DEALLOCATE CPTCURSOR 

然后A

SELECT DISTINCT #VoucherData.Voucher_Number, CPT.CPTCODE 
FROM #VOUCHERDATA  
  LEFT JOIN @CPTTABLE CPT ON CPT.Voucher_Number=#VoucherData.Voucher_Number 

正如我所说,我相信这里有一些非常简单的东西。发生的事情是我将运行此代码并最终得到一个包含数百行的结果集,每一行都是正确的,除了最后一个总是具有CPT的NULL值。

3 个答案:

答案 0 :(得分:1)

您可以使用此代替光标:

使用stuff() with select ... for xml path ('') method of string concatenation

select distinct 
    Voucher_Number
  , stuff((
    select distinct ', ' + i.cpt
      from #Voucherdata i
      where i.Voucher_number = t.Voucher_number
    for xml path (''), type).value('.','nvarchar(max)')
    ,1,2,'')
from #Voucherdata t

答案 1 :(得分:0)

通常使用XML进行字符串聚合:

select v.Voucher_Number, 
       stuff( (select ', ' + cpt
               from #VoucherData v2
               where v2.Voucher_Number = v.Voucher_Number
               for xml path ('')
              ), 1, 2, ''
            ) as codes
from (select distinct Voucher_Number from #VoucherData) v;

如果对同一结果集采用基于集合的方法,则不想使用游标。

答案 2 :(得分:0)

您可能不需要使用游标进行此字符串聚合,您可以使用以下查询:

Select VoucherNumber,  stuff ((
    select ', ' + CPT from #VoucherData where VoucherNumber = t.VoucherNumber 
    for xml path('')
    ),1,2,'') as CPT
From #VoucherData t
Group by VoucherNumber

如果是SQL Server 2017,SQL Azure或PDW,您可以使用String_Agg,如下所示:

Select VoucherNumber, String_Agg(CPT, ', ') as CPT
    from #VoucherData
Group by VoucherNumber