1

我有一张桌子:

+---------+--------------------+--------------------------+
| imd_id  | Total TRx per Plan |        plan name         |
+---------+--------------------+--------------------------+
| 1111005 | 397.1556           | Medicaid Illinois (Idpa) |
| 1111005 | 25.7691            | Self Pay                 |
| 1111005 | 24.4355            | Tricare North Region     |
| 1111005 | 15.0312            | 0                        |
| 1111005 | 8.8425             | 0                        |
| 1111005 | 8.3139             | 0                        |
| 1111005 | 7.0534             | 0                        |
| 1111005 | 6.2588             | 0                        |
| 1111005 | 6.0358             | Bravo Health             |
| 1111005 | 5.9872             | 0                        |
| 1111531 | 133.9664           | Medicaid Al              |
| 1111531 | 29.2318            | 0                        |
| 1111531 | 23.2499            | 0                        |
| 1111531 | 21.9774            | 0                        |
| 1111531 | 14.9269            | 0                        |
| 1111531 | 10.1903            | Self Pay                 |
| 1111531 | 5.4962             | 0                        |
| 1111531 | 5.3409             | Bcbs Federal             |
| 1111531 | 4.4801             | 0                        |
| 1111531 | 3.8003             | 0                        |
+---------+--------------------+--------------------------+

并尝试生成看起来像这样的数据

+---------+--------------------------+----------+---------------+-----------+----------------------+----------+
| imd_id  |      TopFirstPlan       | TopFirst | TopSecondPlan | TopSecond |    TopThirdPlan     | TopThird |
+---------+--------------------------+----------+---------------+-----------+----------------------+----------+
| 1111005 | Medicaid Illinois (Idpa) | 0.78     | Self Pay      | 0.05      | Tricare North Region | 0.04     |
| 1111531 | MEDICAID ALABAMA (AL)    | 0.5      | Self Pay      | 0.04      | Bcbs Federal         | 0.02     |
+---------+--------------------------+----------+---------------+-----------+----------------------+----------+

请注意,创建 TOPFIRST、TOP SECOND、TOP THIRD 的方式是相应的Total TRx per Plan除以该特定 IMD_ID 的计划总和。

到目前为止,我有这个:

 select distinct a.imd_id,'topone'=
    (select top 1 totalrxperplan 
        from book1 b
      where b.imd_id =  a.imd_id)/
      (select SUM(totalrxperplan) 
        from book1 b
        where b.imd_id = a.imd_id)
      ,'topplan2'=
      (select top 1 xifinplanname 
        from book1 b
      where b.imd_id =  a.imd_id)
from book1 a
order by 1 asc

此查询将返回:

+---------+--------------------------+----------+
| imd_id  |      TopFirstPlan1       | TopFirst |
+---------+--------------------------+----------+
| 1111005 | Medicaid Illinois (Idpa) | 79%      |
| 1111531 | MEDICAID ALABAMA (AL)    | 53%      |
+---------+--------------------------+----------+

但我需要添加其他列。

请注意,我们将ignore the plan name where it is 0

4

4 回答 4

3
CREATE TABLE #x(imd_id INT, totalrxperplan FLOAT, xifinplanname NVARCHAR(64));

INSERT #x VALUES
(1111005,397.1556 ,'Medicaid Illinois (Idpa)'),
(1111005,25.7691  ,'Self Pay                '),
(1111005,24.4355  ,'Tricare North Region    '),
(1111005,15.0312  ,'0                       '),
(1111005,8.8425   ,'0                       '),
(1111005,8.3139   ,'0                       '),
(1111005,7.0534   ,'0                       '),
(1111005,6.2588   ,'0                       '),
(1111005,6.0358   ,'Bravo Health            '),
(1111005,5.9872   ,'0                       '),
(1111531,133.9664 ,'Medicaid Al             '),
(1111531,29.2318  ,'0                       '),
(1111531,23.2499  ,'0                       '),
(1111531,21.9774  ,'0                       '),
(1111531,14.9269  ,'0                       '),
(1111531,10.1903  ,'Self Pay                '),
(1111531,5.4962   ,'0                       '),
(1111531,5.3409   ,'Bcbs Federal            '),
(1111531,4.4801   ,'0                       '),
(1111531,3.8003   ,'0                       ');

现在查询:

WITH cte1(id,pn,s) AS 
(
    SELECT imd_id, xifinplanname, 
      ROUND(totalrxperplan/SUM(totalrxperplan) OVER (PARTITION BY imd_id),2,1)
    FROM #x WHERE xifinplanname <> '0'
),
cte2(id,pn,s,rn) AS 
(
    SELECT id,pn,s,ROW_NUMBER() OVER (PARTITION BY id ORDER BY s DESC)
    FROM cte1
)
SELECT 
  id, 
  TopFirstPlan  = MAX(CASE WHEN rn = 1 THEN pn END),
  TopFirst      = MAX(CASE WHEN rn = 1 THEN s  END),
  TopSecondPlan = MAX(CASE WHEN rn = 2 THEN pn END),
  TopSecond     = MAX(CASE WHEN rn = 2 THEN s  END),
  TopThirdPlan  = MAX(CASE WHEN rn = 3 THEN pn END),
  TopThird      = MAX(CASE WHEN rn = 3 THEN s  END)
FROM cte2 
WHERE rn <= 3
GROUP BY id;

如果我的假设是正确的,即输出数字与您的不匹配,因为您想在总数中甚至包含“0”计划,而不是在结果中,那么您可以移动 where 子句:

WITH cte1(id,pn,s) AS 
(
    SELECT imd_id, xifinplanname, 
      ROUND(totalrxperplan/SUM(totalrxperplan) OVER (PARTITION BY imd_id), 2, 1)
    FROM #x -- < -- removed where clause from here
),
cte2(id,pn,s,rn) AS 
(
    SELECT id,pn,CONVERT(DECIMAL(3,2), s),ROW_NUMBER() OVER 
      (PARTITION BY id ORDER BY s DESC)
    FROM cte1 WHERE pn <> '0' -- <-- moved where clause here
)
SELECT 
  id, 
  TopFirstPlan  = MAX(CASE WHEN rn = 1 THEN pn END),
  TopFirst      = MAX(CASE WHEN rn = 1 THEN s  END),
  TopSecondPlan = MAX(CASE WHEN rn = 2 THEN pn END),
  TopSecond     = MAX(CASE WHEN rn = 2 THEN s  END),
  TopThirdPlan  = MAX(CASE WHEN rn = 3 THEN pn END),
  TopThird      = MAX(CASE WHEN rn = 3 THEN s  END)
FROM cte2 
WHERE rn <= 3
GROUP BY id;
于 2012-05-14T18:33:20.623 回答
1

如果我理解正确,关键是通过每个 imd_id 中的总数来枚举组。您可以使用 windows 函数 row_number() 来执行此操作。

最终查询类似于:

select imd_id,
       max(case when therank = 1 then plan_name end) as firstplan,
       max(case when therank = 1 then tot/imd_tot end) as firstplan_ratio,
       ...
from (select t.*, row_number() over (partition by imd_id order by tot desc) as therank,
             sum(tot) over (partition by imd_id) as imd_tot
      from (select imd_id  plan_name, sum(total_trx_per_plan) as tot
            from t
            group by imd_id  plan_name
           ) t
     ) t
group by imd_id
于 2012-05-14T18:28:58.937 回答
1

我不确定 Aaron 的总数,而不是每个 ID 的总数,是 OP 想要的,所以这是我的建议,基本上是 Aaron 建议的,但分数值不同:

更新以纠正错误副本,并考虑“0”规则。

with R1 as (
  select
    imd_id,
    [plan name],
    1e0*[Total TRx per Plan]/sum([Total TRx per Plan]) over (partition by imd_id) as pct,
    row_number() over (
      partition by imd_id
      order by case when [plan name] = '0' then -1 else [Total TRx per Plan] end desc
    ) as rn
  from @Test
) 
  select
    imd_id,
    max(case when rn=1 then [plan name] end) as TopFirstPlan,
    max(case when rn=1 then pct end) as TopFirst,
    max(case when rn=2 then [plan name] end) as TopSecondPlan,
    max(case when rn=2 then pct end) as TopSecond,
    max(case when rn=3 then [plan name] end) as TopThirdPlan,
    max(case when rn=3 then pct end) as TopThird
  from R1
  where rn <= 3
  group by imd_id
  order by imd_id
于 2012-05-14T18:38:03.670 回答
1

我想出了这样的查询:

WITH totals AS (
  SELECT imd_id, sum(t_trx_per_plan) AS ttl
    FROM plans
   GROUP BY imd_id),
ranks(imd_id,t_trx_per_plan,plan_name,prc,rank) AS (
  SELECT p.imd_id,p.t_trx_per_plan,p.plan_name,
    CAST(p.t_trx_per_plan / t.ttl * 100 AS NUMERIC(5,2)) AS prc,
    rank() OVER (PARTITION BY p.imd_id
        ORDER BY (p.t_trx_per_plan / t.ttl * 100) DESC) AS rank
    FROM plans p
    JOIN totals t ON t.imd_id = p.imd_id
   WHERE p.plan_name != '0')
SELECT
    ttl.imd_id,
    f.plan_name AS "FirstPlan",f.prc AS "First",
    s.plan_name AS "SecondPlan",s.prc AS "Second",
    t.plan_name AS "ThirdPlan",t.prc AS "Third"
  FROM totals ttl
  LEFT JOIN ranks f ON f.imd_id = ttl.imd_id AND f.rank = 1
  LEFT JOIN ranks s ON s.imd_id = ttl.imd_id AND s.rank = 2
  LEFT JOIN ranks t ON t.imd_id = ttl.imd_id AND t.rank = 3;

第一个 CTEtotals给出了imd_id每个计划的总交易量列表。第二个CTEranks是排名计划。请注意,我使用了rank()函数,如果计划每个计划具有相同数量的事务,它将产生相同的排名。如果要正确处理此类情况,则需要使用row_number()窗口函数并在子句中添加额外的ORDER BYOVER,唯一的可能是使用:

row_number() OVER (PARTITION BY p.imd_id
    ORDER BY (p.t_trx_per_plan / t.ttl * 100) DESC, p.plan_name) AS rank

您可以在此处检查输出。

于 2012-05-14T19:14:52.737 回答