首页 > 解决方案 > 是否可以根据变量的数量在 case 语句中重复 when 子句?

问题描述

作为我工作的一部分,我需要创建理赔档案。这是关于我的工作的一个快速想法。

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

625 起 0 - 1000 美元的索赔,总报销 51 万美元,
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 子句的数量,那将是很棒的。

标签: sqlsql-servercase-statement

解决方案


我建议您创建一个分类表,而不是激增硬编码的 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);

您现在可以使用数据驱动的方法,通过将 Claims 加入到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 示例在这里

笔记

  • 您需要注意分类表的边缘 - 在此处的示例中,下限包含在内,但上限不包含在内。
  • 例如,您还可以使用NULL来指示没有上限或下限,然后相应地调整查询。
  • 您需要检查您的频段是否相互重叠,否则同一声明将被分类为多个频段。

推荐阅读