显示具有列的特定值的最大计数的行
Showing rows with greatest count of a specific value of a column
我有这个查询:
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
哪个returns这个结果集:
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
按您分组 dealer_number 并使用如下构造有条件地对计数求和: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
我有这个查询:
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
哪个returns这个结果集:
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
按您分组 dealer_number 并使用如下构造有条件地对计数求和: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