是否可以根据变量的数量在case语句中重复when子句?

时间:2018-06-08 11:41:37

标签: sql sql-server case-statement

作为我工作的一部分,我需要创建理赔案例。这是我对工作的快速了解。

我们收到索赔数据。我需要创建索赔概况的报告,其中我们提到索赔额的范围和相应的索赔数量以及该范围内的总报销额。例子可能是 -

625件索赔$ 0 - $ 1000,总报销额为$ 510k,
   862美元索赔1001美元 - 5000美元,总偿还额为301万美元,    334索赔$ 5001 - $ 10000,总偿还额为260万美元。

乐队或乐队的数量总是有一些变化。因此,下次相同的范围可能需要6个频段,而不是3.我已经自动化几乎报告的所有其他部分。但是不能这样做。我可以创建一个程序,我可以提到所需的频段数和频段的下限/上限。但那时它还没有完全自动化。我的想法是,我在查询的开头提到了乐队的数量和界限。之后我不需要改变查询的任何部分。

以下是我的努力

DECLARE @Range1 varchar(10)
DECLARE @Range2 varchar(10)
DECLARE @Range3 varchar(10)

SET @Range1 = '0'
SET @Range2 = '1000'
SET @Range3 = '5000'

   SELECT
   CASE WHEN ROUND(clmamt, 0) between ' + @Range1 + ' and ' + @Range2 + ' THEN ''1. $' + @Range1 + ' - $' + @Range2 + '''
        WHEN ROUND(clmamt, 0) between ' + @Range2 + ' and ' + @Range3 + ' THEN ''2. $' + @Range2 + ' - $' + @Range3 + '''
        WHEN ROUND(clmamt, 0) > ' + @Range3 + ' THEN ''3. > $' + @Range3 + '''
        ELSE ''ERROR'' END AS 'Range',
   SUM(clmamt) 'Total Reimbursement', COUNT(l.CLMID ) as 'Total Claims'

        from
   TableA l join
        (
         select CLMID, SUM(clm) 'clmamt' from TableAB
         group by CLMID
        )lc on l.CLMID = lc.CLMID join 
   TableB pt on l.ACCNTID = pt.ACCNTID join
   TableC pn on pt.GROUPID = pn.GROUPID
   where pt.GROUPID in (1,2)
   Group by        CASE WHEN ROUND(clmamt, 0) between 0 and 1000 THEN '1. $0- $1000'
                        WHEN ROUND(clmamt, 0) between 1001 and 5000 THEN '2. $1001- $5000'
                        WHEN ROUND(clmamt, 0) > 5001 THEN '3. > $5000'
                        ELSE 'ERROR' END

如果我可以做一些我可以添加变量来表示每个波段的波段数和范围的事情。并且自动查询会在CASE语句中添加when子句的数量,这样会很棒。

1 个答案:

答案 0 :(得分:1)

我建议您创建一个分类表,然后根据索赔金额加入分类表,然后按每个频段对索赔进行分组,即

,而不是扩散硬编码的CASE语句。
CREATE TABLE ClaimBand
(
    Name NVARCHAR(20),
    MinAmount NUMERIC(10,2),
    MaxAmount NUMERIC(10,2),
);

INSERT INTO ClaimBand(Name, MinAmount, MaxAmount) VALUES
('Small Claims', 0, 1000),
('Medium Claims', 1000, 5000),
('Large Claims', 5000, 10000),
('Super Large Claims', 10000, 999999);

您现在可以使用数据驱动方法,将声明加入ClaimBand表,根据ClaimBand中的行而非代码对声明进行分类:

SELECT band.Name, band.MinAmount, band.MaxAmount, 
       COUNT(*) AS NumClaims, SUM(c.Amount) AS TotalClaimed
FROM Claim c
INNER JOIN ClaimBand band on c.Amount >= band.MinAmount and c.Amount < band.MaxAmount
GROUP BY band.Name, band.MinAmount, band.MaxAmount;

SqlFiddle example here

备注

  • 您需要对分类表的边缘有点小心 - 在此示例中,下限是包含的,但上限是独占的。
  • 您还可以使用NULL来表示没有上限或下限,然后相应地调整查询。
  • 您需要检查您的乐队是否相互重叠,否则相同的声明将被归类为多个乐队。