显示具有列的特定值的最大计数的行

时间:2015-02-17 18:19:12

标签: sql sql-server tsql

我有这个问题:

select 
    d.sdealer_number
    ,c.icontract_term
    ,case when (c.icontract_term / 12) = 0 THEN cast(c.icontract_term as varchar) + ' M' ELSE cast((c.icontract_term / 12) as varchar) + ' Y' END as Term
    ,count(c.icontract_term) as [Count]
from dealers d
inner join contracts c on c.sdealer_number = d.sdealer_number
where d.sdealer_number not like '%demo%'
group by c.icontract_term, d.sdealer_number
order by d.sdealer_number

返回此结果集:

sdealer_number  icontract_term  Term    Count
DL00001             84  7 Y 3
DL00001             12  1 Y 12
DL00001             48  4 Y 15
DL00001             60  5 Y 2
DL00001             24  2 Y 2
DL00001             3   3 M 1
DL00001             6   6 M 5
DL00001             36  3 Y 1
DL00002             84  7 Y 4
DL00002             48  4 Y 2
DL00002             6   6 M 35
DL00002             3   3 M 8
DL00002             12  1 Y 8
DL00002             36  3 Y 2
DL00007             36  3 Y 1
DL00007             12  1 Y 1
DL00007             60  5 Y 4
DL00007             24  2 Y 2
DL00007             48  4 Y 9
DL00007             84  7 Y 1

我需要过滤结果集,并且只显示4 Y(48个月期限)和5 Y(60个月期限)是销售合约的大部分行。

因此,在上面的示例中,DL00001不应显示,也不应显示DL00002,但DL00007应显示,因为他们销售的4-5 Y条款合约多于任何其他他们卖的合约类型。


编辑:

以下是与@MWillemse一起使用的信用解决方案:

; with t as (select d.sdealer_number, sum(case when c.icontract_term in (48,60) then 1 else 0 end) as '4-5 Yeam Term', sum(case when c.icontract_term not in (48,60) then 1 else 0 end) as 'Non 4-5 Yeam Term'
from dealers d
inner join contracts c on c.sdealer_number = d.sdealer_number
where d.sdealer_number not like '%demo%'
group by d.sdealer_number)
select * from t
where t.[4-5 Yeam Term] > t.[Non 4-5 Yeam Term]
order by sdealer_number

1 个答案:

答案 0 :(得分:0)

由经销商分组,并使用如下构造有条件地对计数求和:SUM(CASE WHEN Term IN ( '4 Y', '5 Y' ) THEN [Count] ELSE 0 END)并使用having子句来过滤要保留的组。

编辑:重新阅读您的查询后,我意识到您需要过滤结果,而不是将它们完全分组。以下查询可能更适合您的需求。

WITH    
YourOriginalQuery
    AS (SELECT    d.sdealer_number
                , c.icontract_term
                , CASE WHEN (c.icontract_term / 12) = 0 THEN CAST(c.icontract_term AS VARCHAR) + ' M'
                        ELSE CAST((c.icontract_term / 12) AS VARCHAR) + ' Y'
                END AS Term
                , COUNT(c.icontract_term) AS [Count]
        FROM      dealers d
        INNER JOIN contracts c ON c.sdealer_number = d.sdealer_number
        WHERE     d.sdealer_number NOT LIKE '%demo%'
        GROUP BY  c.icontract_term
                , d.sdealer_number
        ) ,
Totals
    AS (SELECT    YOQ.*
                , Y45Total = SUM(CASE WHEN Term IN ('4 Y', '5 Y') THEN 1
                                    ELSE 0
                                END) OVER (PARTITION BY dealer_number)
                , NY45Total = SUM(CASE WHEN Term NOT IN ('4 Y', '5 Y') THEN 1
                                        ELSE 0
                                END) OVER (PARTITION BY dealer_number)
        FROM      YourOriginalQuery AS YOQ
        )
SELECT *
FROM   Totals
WHERE  Totals.Y45Total > Totals.NY45Total
ORDER BY  d.sdealer_number