高级分组 - 拉动最近的事务,但保持分组

时间:2014-07-18 21:51:13

标签: sql sql-server tsql grouping

我有一个相当复杂的查询,我似乎无法按顺序获得正确的组。除了分组外,一切都顺利进行。问题是我需要从中提取产品和子产品,但我还需要提取最新的交易,因为有重复的' (它们不是真正重复的行,但是不拉动最近的交易会大大增加总和)。更具体地说,我通过内部加入最近的交易和我从表中选择的内容来拉动最近的交易:

INNER JOIN (select fp.pol_num
                      ,MAX(fp.id_prem) id_prem
                 from bapu.dbo.fact_prem fp
                 group by fp.pol_num) max_trans_id
        on fp.pol_num = max_trans_id.pol_num
       and fp.id_prem = max_trans_id.id_prem

这就是弄乱我的分组。发生的事情是,所有人的总和都是'正在与最新的子产品连在一起。因此,例如,如果策略有3个覆盖范围:一般责任,商业自动和工人补偿,则所有这三个覆盖范围的总和仅添加到已编辑的最后一行。我需要保持产品的结构 - 子产品,这样每个子产品都有正确的总和,而不是一个子产品类型显示的所有3个的总和。我已经尝试更改拉取最近事务的子查询,以及group by语句,但这似乎只是让事情有效。这是我正在运行的查询:

DECLARE @d_inforce date; SET @d_inforce = '2014-06-01'


select limit_group_list.limit_group as 'Limit Band'
      ,pol_dtl.product
      ,pol_dtl.sub_product
      ,SUM(COALESCE(pol_dtl.gross_premium,0)) as 'Gross Premium'
      ,COUNT(distinct pol_dtl.pol_num) as 'Policy Count'
      ,SUM(COALESCE(pol_dtl.limit,0)) as 'Limit'
from
(select pol_product.pol_num
      ,pol_product.product
      ,pol_product.sub_product
      ,pol_premcomm.gross_premium
      ,pol_premcomm.commission
      ,pol_premcomm.net_premium
      ,pol_limit.lmt_pol_s as limit
      ,pol_limit.Limit_Order
      ,pol_limit.Limit_Group
from
-- Pull product for each policy from the most recent transaction
(select fp.pol_num
       ,fp.product
       ,fp.sub_product
 from bapu.dbo.fact_prem fp
 INNER JOIN (select fp.pol_num
                   ,MAX(fp.id_prem) id_prem
             from bapu.dbo.fact_prem fp
             group by fp.pol_num) max_trans_id
    on fp.pol_num = max_trans_id.pol_num
   and fp.id_prem = max_trans_id.id_prem
 -- Inforce Logic
 where @d_inforce between fp.d_pol_eff and fp.d_pol_exp
   and fp.pol_num not in (select distinct pol_num from bapu.dbo.fact_prem where lower(trans) like 'canc%' and d_tran_eff <= @d_inforce)
) pol_product
LEFT OUTER JOIN
-- Pull premium, commission, and net_premium per policy number
(select prem_comm.pol_num as pol_num
       ,prem_comm.gross_premium as gross_premium
       ,prem_comm.commission as commission
       ,COALESCE(prem_comm.gross_premium,0) - COALESCE(prem_comm.commission,0) as net_premium
 from
 (select fp.pol_num
        ,SUM(CASE
               WHEN fp.amt_type = 'Premium' THEN fp.amt
               ELSE 0
             END) as gross_premium
        ,SUM(CASE
               WHEN fp.amt_type = 'Add_Ded' and fp.amt_desc = 'Commission' THEN fp.amt
               ELSE 0
             END) as commission
  from bapu.dbo.fact_prem fp
 group by fp.pol_num) prem_comm) pol_premcomm
ON pol_product.pol_num = pol_premcomm.pol_num
LEFT OUTER JOIN
-- Pull limit bands per policy
    (SELECT pol_lmt.pol_num
      ,pol_lmt.lmt_pol_s
      ,CASE 
        WHEN pol_lmt.lmt_pol_s >= 50000001 AND pol_lmt.lmt_pol_s <= 100000000 THEN 20
        WHEN pol_lmt.lmt_pol_s >= 40000001 AND pol_lmt.lmt_pol_s <=  50000000 THEN 19
        WHEN pol_lmt.lmt_pol_s >= 30000001 AND pol_lmt.lmt_pol_s <=  40000000 THEN 18
        WHEN pol_lmt.lmt_pol_s >= 20000001 AND pol_lmt.lmt_pol_s <=  30000000 THEN 17
        WHEN pol_lmt.lmt_pol_s >= 15000001 AND pol_lmt.lmt_pol_s <=  20000000 THEN 16
        WHEN pol_lmt.lmt_pol_s >= 14000001 AND pol_lmt.lmt_pol_s <=  15000000 THEN 15
        WHEN pol_lmt.lmt_pol_s >= 13000001 AND pol_lmt.lmt_pol_s <=  14000000 THEN 14
        WHEN pol_lmt.lmt_pol_s >= 12000001 AND pol_lmt.lmt_pol_s <=  13000000 THEN 13
        WHEN pol_lmt.lmt_pol_s >= 11000001 AND pol_lmt.lmt_pol_s <=  12000000 THEN 12
        WHEN pol_lmt.lmt_pol_s >= 10000001 AND pol_lmt.lmt_pol_s <=  11000000 THEN 11
        WHEN pol_lmt.lmt_pol_s >=  9000001 AND pol_lmt.lmt_pol_s <=  10000000 THEN 10
        WHEN pol_lmt.lmt_pol_s >=  8000001 AND pol_lmt.lmt_pol_s <=   9000000 THEN 9
        WHEN pol_lmt.lmt_pol_s >=  7000001 AND pol_lmt.lmt_pol_s <=   8000000 THEN 8
        WHEN pol_lmt.lmt_pol_s >=  6000001 AND pol_lmt.lmt_pol_s <=   7000000 THEN 7
        WHEN pol_lmt.lmt_pol_s >=  5000001 AND pol_lmt.lmt_pol_s <=   6000000 THEN 6
        WHEN pol_lmt.lmt_pol_s >=  4000001 AND pol_lmt.lmt_pol_s <=   5000000 THEN 5
        WHEN pol_lmt.lmt_pol_s >=  3000001 AND pol_lmt.lmt_pol_s <=   4000000 THEN 4
        WHEN pol_lmt.lmt_pol_s >=  2000001 AND pol_lmt.lmt_pol_s <=   3000000 THEN 3
        WHEN pol_lmt.lmt_pol_s >=  1000001 AND pol_lmt.lmt_pol_s <=   2000000 THEN 2
        WHEN pol_lmt.lmt_pol_s >=        1 AND pol_lmt.lmt_pol_s <=   1000000 THEN 1
        ELSE 0 
    END AS Limit_Order
      ,CASE 
        WHEN pol_lmt.lmt_pol_s >= 50000001 AND pol_lmt.lmt_pol_s <= 100000000 THEN '$50,000,001-$100,000,000'
        WHEN pol_lmt.lmt_pol_s >= 40000001 AND pol_lmt.lmt_pol_s <=  50000000 THEN '$40,000,001-$50,000,000'
        WHEN pol_lmt.lmt_pol_s >= 30000001 AND pol_lmt.lmt_pol_s <=  40000000 THEN '$30,000,001-$40,000,000'
        WHEN pol_lmt.lmt_pol_s >= 20000001 AND pol_lmt.lmt_pol_s <=  30000000 THEN '$20,000,001-$30,000,000'
        WHEN pol_lmt.lmt_pol_s >= 15000001 AND pol_lmt.lmt_pol_s <=  20000000 THEN '$15,000,001-$20,000,000'
        WHEN pol_lmt.lmt_pol_s >= 14000001 AND pol_lmt.lmt_pol_s <=  15000000 THEN '$14,000,001-$15,000,000'
        WHEN pol_lmt.lmt_pol_s >= 13000001 AND pol_lmt.lmt_pol_s <=  14000000 THEN '$13,000,001-$14,000,000'
        WHEN pol_lmt.lmt_pol_s >= 12000001 AND pol_lmt.lmt_pol_s <=  13000000 THEN '$12,000,001-$13,000,000'
        WHEN pol_lmt.lmt_pol_s >= 11000001 AND pol_lmt.lmt_pol_s <=  12000000 THEN '$11,000,001-$12,000,000'
        WHEN pol_lmt.lmt_pol_s >= 10000001 AND pol_lmt.lmt_pol_s <=  11000000 THEN '$10,000,001-$11,000,000'
        WHEN pol_lmt.lmt_pol_s >=  9000001 AND pol_lmt.lmt_pol_s <=  10000000 THEN '$9,000,001-$10,000,000'
        WHEN pol_lmt.lmt_pol_s >=  8000001 AND pol_lmt.lmt_pol_s <=   9000000 THEN '$8,000,001-$9,000,000'
        WHEN pol_lmt.lmt_pol_s >=  7000001 AND pol_lmt.lmt_pol_s <=   8000000 THEN '$7,000,001-$8,000,000'
        WHEN pol_lmt.lmt_pol_s >=  6000001 AND pol_lmt.lmt_pol_s <=   7000000 THEN '$6,000,001-$7,000,000'
        WHEN pol_lmt.lmt_pol_s >=  5000001 AND pol_lmt.lmt_pol_s <=   6000000 THEN '$5,000,001-$6,000,000'
        WHEN pol_lmt.lmt_pol_s >=  4000001 AND pol_lmt.lmt_pol_s <=   5000000 THEN '$4,000,001-$5,000,000'
        WHEN pol_lmt.lmt_pol_s >=  3000001 AND pol_lmt.lmt_pol_s <=   4000000 THEN '$3,000,001-$4,000,000'
        WHEN pol_lmt.lmt_pol_s >=  2000001 AND pol_lmt.lmt_pol_s <=   3000000 THEN '$2,000,001-$3,000,000'
        WHEN pol_lmt.lmt_pol_s >=  1000001 AND pol_lmt.lmt_pol_s <=   2000000 THEN '$1,000,001-$2,000,000'
        WHEN pol_lmt.lmt_pol_s >=        1 AND pol_lmt.lmt_pol_s <=   1000000 THEN '$0-$1,000,000'

        ELSE 'Unknown' 
      END AS Limit_Group
    FROM 
      (select fp.pol_num
             ,MAX(lmt_pol_s) lmt_pol_s
       from bapu.dbo.fact_prem fp
       where fp.amt_type = 'Premium'
       and fp.product in (
'Package',
'Package - Crime',
'Package - Fine Art',
'Package - Jewelers Block',
'Package - Specie')
       group by fp.pol_num) pol_lmt
       ) pol_limit

 ON pol_product.pol_num = pol_limit.pol_num
 where pol_product.product in (
'Package',
'Package - Crime',
'Package - Fine Art',
'Package - Jewelers Block',
'Package - Specie')
 and pol_product.sub_product in(
                        'Umbrella/Excess',
                        'Workers Compensation',
                        'General Liability',
                        'Commercial Auto',
                        'Commercial Property')
                        ) as pol_dtl
RIGHT OUTER JOIN
(select distinct fp.product 
               ,lmtgrp.limit_group
from bapu.dbo.fact_prem fp
cross join
(select '$50,000,001-$100,000,000' limit_group
 UNION
 select '$40,000,001-$50,000,000'
 UNION
 select '$30,000,001-$40,000,000'
  UNION
 select '$20,000,001-$30,000,000'
  UNION
 select '$15,000,001-$20,000,000'
 UNION
 select '$14,000,001-$15,000,000'
 UNION 
 select '$13,000,001-$14,000,000'
 UNION
 select '$12,000,001-$13,000,000'
 UNION
 select '$11,000,001-$12,000,000'
 UNION
 select '$10,000,001-$11,000,000'
 UNION
 select '$9,000,001-$10,000,000'
 UNION
 select '$8,000,001-$9,000,000'
 UNION
 select '$7,000,001-$8,000,000'
 UNION
 select '$6,000,001-$7,000,000'
 UNION
 select '$5,000,001-$6,000,000'
 UNION
 select '$4,000,001-$5,000,000'
 UNION
 select '$3,000,001-$4,000,000'
 UNION
 select '$2,000,001-$3,000,000'
 UNION
 select '$1,000,001-$2,000,000'
 UNION
 select '$0-$1,000,000'
 UNION
 select 'Unknown') lmtgrp
 where  fp.product in (
'Package',
'Package - Crime',
'Package - Fine Art',
'Package - Jewelers Block',
'Package - Specie')
  and fp.sub_product in(
                        'Umbrella/Excess',
                        'Workers Compensation',
                        'General Liability',
                        'Commercial Auto',
                        'Commercial Property')              
 ) limit_group_list
 on pol_dtl.product = limit_group_list.product
and pol_dtl.Limit_Group = limit_group_list.limit_group
group by pol_dtl.Limit_Group, pol_dtl.Limit_Order, pol_dtl.product, limit_group_list.limit_group, sub_product
order by pol_dtl.product, pol_dtl.Limit_Order

1 个答案:

答案 0 :(得分:0)

首先,我建议不要对表和子查询(fp)使用相同的别名,这使得很难遵循:S

其次,您可以使用以下查询替换group / max查询以获取最新的行

INNER JOIN (select subfp.pol_num
                 , subfp.id_prem
                 , ROW_NUMBER() OVER(PARTITION BY subfp.pol_num ORDER BY subfp.id_prem DESC) AS priority
             from bapu.dbo.fact_prem subfp
             ) max_trans_id
    on fp.pol_num = max_trans_id.pol_num
   and fp.id_prem = max_trans_id.id_prem
   and max_trans_id.priority = 1

我希望这会有所帮助

相关问题