SQL Server存储过程 - 将多行中的列拉入一行

时间:2013-03-07 16:11:07

标签: sql sql-server stored-procedures

我正在研究SQL存储过程,将患者计费数据提取到数据集(然后将其返回到VB.net应用程序)。

我的问题:一个患者在一个结算周期/项目中可能在表格中有多行,但行中只有3个字段会有所不同。我不想每次都把每一行完全拉出来。我想要第一次所有的领域,然后下一次只是不同的领域。我希望所有记录都在一行中。

我无法提前知道此患者在这一个结算周期/项目的表格中有多少行,但最大值为10。

表格中有一个claim_id字段,该字段是每个结算周期/项目特定的患者,因此可以重复(并且是我用来提取记录的内容)。表中还有一个ID字段,它是一个Identity列,因此它对每条记录都是唯一的。

我当前的存储过程:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [BillClm] 
@ClaimId varchar(20),
@AccountCode integer

AS

SET NOCOUNT ON;

declare @PatientGridTable table
(
    Claim_Submitters_Id varchar(20),
    Claim_Status_Code varchar(2),
    Total_Amount_of_Claim decimal(18,2),
    Claim_Payment_Amt decimal(18,2),
    Claim_Patient_Resp decimal(18,2),
    Claim_Filing_Ind_Code varchar(2),
    Payor_Claim_Control_Num varchar(30),
    Bill_Type integer,
    Claim_Adjustment_Group_Reason_Code varchar(10),
    Claim_Adjustment_Amount decimal(18,2),
    Claim_Adjustment_Quantity integer,  
    Patient_Name varchar(60),
    Patient_ID_Num varchar(50),
    Insured_Name varchar(60),
    Insured_ID_Num varchar(50),
    Other_Payor_Name varchar(60),
    Other_Payor_ID varchar(80),
    Other_Subscriber_Name varchar(60),
    Other_Subscriber_ID varchar(80),
    Covered_Quantity integer,
    Covered_Amount decimal(18,2),
    Reimbursement_Rate decimal(6,2),
    Remark_Code varchar(2500),  
    Statement_Period_Start_End varchar(25)
)

insert into @PatientGridTable
(
    Claim_Submitters_Id,
    Claim_Status_Code,
    Total_Amount_of_Claim,
    Claim_Payment_Amt,
    Claim_Patient_Resp,
    Claim_Filing_Ind_Code,
    Payor_Claim_Control_Num,
    Bill_Type,
    Claim_Adjustment_Group_Reason_Code,
    Claim_Adjustment_Amount,
    Claim_Adjustment_Quantity,  
    Patient_Name,
    Patient_ID_Num,
    Insured_Name,
    Insured_ID_Num,
    Other_Payor_Name,
    Other_Payor_ID,
    Other_Subscriber_Name,
    Other_Subscriber_ID,
    Covered_Quantity,
    Covered_Amount,
    Reimbursement_Rate,
    Remark_Code,    
    Statement_Period_Start_End
)
select  
    d.submitter_id, d.claim_status, d.claim_amt, d.payment_amt,
    d.patient_resp, d.claim_ind, d.ref_num, d.bill_type,
    (a.adj_group_code+' '+a.adj_reason_code), a.adj_amount,
    a.adj_qty, d.patient_name, d.patient_id, d.insured_name,
    d.insured_id, d.other_payor, d.other_payor_id, d.other_subscriber,
    d.other_subscriber_id, d.days, d.amount, d.percent,
    (d.adj_ref+'_'+c.code_text),
    (CONVERT(varchar(12), d.claim_start_date, 101)+' '+CONVERT(varchar(12),         d.claim_end_date,101))
    FROM clm_detail_patient d  WITH(NOLOCK)
    INNER JOIN code_list c  WITH(NOLOCK) 
    ON d.adj_ref = c.map_id
    INNER JOIN clm_adj a  WITH(NOLOCK)
    ON d.claim_id = a.claim_id    
    WHERE d.claim_id = @ClaimId     

-- -----------------------------------------------------------------------
select * from @PatientGridTable

clm_adj是可以返回0到10行的表 - 通过claim_id字段绑定到clm_detail_patient表。 (clm_detail_patient将始终只有一行。)

clm_adj表中每行不同的三个字段是:     Claim_Adjustment_Group_Reason_Code,     Claim_Adjustment_Amount,     Claim_Adjustment_Quantity

我喜欢的是,对于clm_adj中的每个不同的行,这三个字段在一行中彼此相邻。我不确定如何做到这一点。

如果有更好的方法可以去这里,我不会做临时表。任何帮助将不胜感激!

示例clm_detail_patient表数据:

id     code      amt        payment    pat_resp   clm_ind    ref_num          bill     pat_name          pat_id      days    amount      pct   adj_ref  start_dt      end_date       claim_id
12345    19    15344.43    14962.12    2456.50    MA        20122580231ABC    213    DOE, JANE           123456789B    0    17418.62    0.00    MA01    2012-10-01    2012-10-31    1234-A00000000000001
12346    19    9157.21     8128.58     289.00     MA        20122580231ABC    212    SMITH, JOHN         987654321B    0    8417.58     0.00    MA01    2012-10-10    2012-10-31    4567-A00000000000001
12347    1     2522.99     1143.66     0.00       MA        20122580231ABC    211    JONES, MARY         987123456B    0    1143.66     0.00    MA01    2012-10-14    2012-10-17    9876-A00000000000001

示例clm_adj表数据:

adj  reason   amt      qty   claim_id
CO    45    -2074.19    0    1234-A00000000000001
PR    2     2456.50     0    1234-A00000000000001
CO    45    739.63      0    4567-A00000000000001
PR    2     289.00      0    4567-A00000000000001
CO    45    1379.33     0    9876-A00000000000001

每个表中的最后一个字段是claim_id。

所以前两个患者在clm_adj表中有两个记录,第三个患者只有一个。

如果我要为患者#1运行我当前的存储过程,我会得到两行。我想为第一位患者看到的是什么:

12345    19    15344.43    14962.12    2456.50    MA        20122580231ABC    213    CO 45    -2074.19    0    PR 2    2456.50    0    DOE, JANE           123456789B    0    17418.62    0.00    MA01    2012-10-01  2012-10-31    1234-A00000000000001

因此,两个adj / reason,amount和quantity字段记录显示在一行上,彼此相邻(从第九个字段中的CO 45开始)。

1 个答案:

答案 0 :(得分:1)

按照Esoteric Sc​​reen Name提供的链接,我能够解决问题。在声明患者网格表之前,我将以下内容插入到我的存储过程中:

DECLARE @combinedClaimString VARCHAR(MAX)
SELECT @combinedClaimString = COALESCE(@combinedClaimString + '; ', '') + adj_group_code + ', ' + adj_reason_code + ', ' + (SELECT CONVERT(varchar(22), adj_amount)) + ', ' + (SELECT CONVERT(varchar(22), adj_qty))
FROM (SELECT  adj_group_code, adj_reason_code, adj_amount, adj_qty, claim_id 
FROM br549.clm_adj
WHERE claim_id = @ClaimId)
AS temp

这导致一个字符串,索引的每个部分用逗号分隔,每个声明用分号分隔。

然后我修改了PatientGridTable结构,只包含一个字段用于所有声明信息:

declare @PatientGridTable table
(
    Claim_Submitters_Id varchar(20),
    Claim_Status_Code varchar(2),
    Total_Amount_of_Claim decimal(18,2),
    Claim_Payment_Amt decimal(18,2),
    Claim_Patient_Resp decimal(18,2),
    Claim_Filing_Ind_Code varchar(2),
    Payor_Claim_Control_Num varchar(30),
    Bill_Type integer,
    Claim_Adjustment varchar(MAX),  
    Patient_Name varchar(60),
    Patient_ID_Num varchar(50),
    Insured_Name varchar(60),
    Insured_ID_Num varchar(50),
    Other_Payor_Name varchar(60),
    Other_Payor_ID varchar(80),
    Other_Subscriber_Name varchar(60),
    Other_Subscriber_ID varchar(80),
    Covered_Quantity integer,
    Covered_Amount decimal(18,2),
    Reimbursement_Rate decimal(6,2),
    Remark_Code varchar(2500),  
    Statement_Period_Start_End varchar(25)
)

然后我将@combinedClaimString变量选择到PatientGridTable:

insert into @PatientGridTable
(
    Claim_Submitters_Id,
    Claim_Status_Code,
    Total_Amount_of_Claim,
    Claim_Payment_Amt,
    Claim_Patient_Resp,
    Claim_Filing_Ind_Code,
    Payor_Claim_Control_Num,
    Bill_Type,
    Claim_Adjustment,  
    Patient_Name,
    Patient_ID_Num,
    Insured_Name,
    Insured_ID_Num,
    Other_Payor_Name,
    Other_Payor_ID,
    Other_Subscriber_Name,
    Other_Subscriber_ID,
    Covered_Quantity,
    Covered_Amount,
    Reimbursement_Rate,
    Remark_Code,    
    Statement_Period_Start_End
)
select  
    d.submitter_id, d.claim_status, d.claim_amt, d.payment_amt,
    d.patient_resp, d.claim_ind, d.ref_num, d.bill_type,
    (SELECT @combinedClaimString as adj_group_code), d.patient_name, d.patient_id, d.insured_name, d.insured_id, d.other_payor, d.other_payor_id, d.other_subscriber,
    d.other_subscriber_id, d.days, d.amount, d.percent,
    (d.adj_ref+'_'+c.code_text),
    (CONVERT(varchar(12), d.claim_start_date, 101)+' '+CONVERT(varchar(12),         d.claim_end_date,101))
    FROM clm_detail_patient d  WITH(NOLOCK)
    INNER JOIN code_list c  WITH(NOLOCK) 
    ON d.adj_ref = c.map_id
    INNER JOIN clm_adj a  WITH(NOLOCK)
    ON d.claim_id = a.claim_id    
    WHERE d.claim_id = @ClaimId

数据集将返回到我的应用程序,每位患者只有一行。然后,我可以将声明字符串拆分为适当的格式。

非常感谢Esoteric Sc​​reen Name!