SQL Server - Top Saleperson لكل منطقة
-
21-09-2019 - |
سؤال
SELECT region, person, sum(dollars) as thousands
FROM sales
GROUP BY region, person
ORDER BY region, sum(dollars) desc
تنتج SQL أعلاه قائمة كاملة من موظفي المبيعات لكل منطقة مثل هذه
region person thousands
canada mike smith $114
canada joe blog $76
canada pete dodd $45
usa john doe $253
usa jane smyth $120
europe pieter tsu $546
europ mike lee $520
إذا كنت مهتمًا فقط بإظهار أفضل مندوب المبيعات لكل منطقة (على النحو التالي) ، كيف يمكنني القيام بذلك على أفضل وجه؟
region person thousands
canada mike smith $114
usa john doe $253
europe pieter tsu $546
المحلول
لقد فعلت شيئًا مثل بيرنال اقترح. لم أكن أحب الكثير مع جزء "Top 1 with ties" ، لذلك جعلت الأمر برمته مساعًا فرعيًا واخترت صفوفًا حيث الترتيب = 1.
select *
from
(
select region,
person,
rank() over(partition by region order by sum(dollars) desc) as ranking
from sales
group by region,
person
) temp
where ranking = 1
لاحظ أن هذا يعمل أيضًا مع العلاقات لأن الرتبة () يبدو أنه يضع نفس الترتيب على مبالغ متساوية.
نصائح أخرى
باستخدام SQL Server 2005+ يمكنك القيام بذلك باستخدام أ رقم الصف()
إلقاء نظرة على هذا المثال الكامل.
DECLARE @sales TABLE(
region VARCHAR(50),
person VARCHAR(50),
Sales FLOAT
)
INSERT INTO @sales SELECT 'canada','mike smith',1
INSERT INTO @sales SELECT 'canada','mike smith',1
INSERT INTO @sales SELECT 'canada','mike smith',1
INSERT INTO @sales SELECT 'canada','mike smith',1
INSERT INTO @sales SELECT 'canada','joe blog',1
INSERT INTO @sales SELECT 'canada','joe blog',1
INSERT INTO @sales SELECT 'canada','pete dodd',1
INSERT INTO @sales SELECT 'usa','john doe',1
INSERT INTO @sales SELECT 'usa','john doe',1
INSERT INTO @sales SELECT 'usa','jane smyth',1
INSERT INTO @sales SELECT 'europe','pieter tsu',1
INSERT INTO @sales SELECT 'europe','pieter tsu',1
INSERT INTO @sales SELECT 'europe','mike lee',1
;WITH Counts AS(
SELECT region,
person,
count(*) as thousands
FROM @sales
GROUP BY region,
person
), CountVals AS(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY region ORDER BY thousands DESC) ROWID
FROM Counts
)
SELECT *
FROM CountVals
WHERE ROWID = 1
في SQL Server 2005 وما فوق الاستخدام ROW_NUMBER
مع PARTITION BY
. يجب أن يعمل التالية (لم يتم اختبارها ، وربما يمكن تقصيرها):
WITH total_sales
AS (SELECT region, person, count(*) as thousands
FROM sales
GROUP BY region, person
ORDER BY region, count(*) desc
)
, ranked_sales
AS (SELECT region, person, thousands,
ROW_NUMBER() OVER (PARTITION BY region ORDER BY thousands DESC, person) AS region_rank
FROM total_sales
)
SELECT region, person, thousands
FROM ranked_sales
WHERE region_rank = 1
بادئ ذي بدء ، لا أفهم سبب كون العد (*) في $. إن حلي مشابه للقائمة ، ولكنه أقصر وأعتقد بشكل أسرع
select top 1 with ties region, person, rank() over(partition by region order by count(*) desc)
from sales
group by region, person
order by 3
هذا ليس صعبًا جدًا. هذا الاستعلام سوف يفعل بالضبط ما تريد.
select distinct region,
(select top 1 person
from Sales s2 where s2.region = s1.region
group by person
order by SUM(dollars) desc) as person,
(select top 1 SUM(dollars)
from Sales s2 where s2.region = s1.region
group by person
order by SUM(dollars) desc) as thousands
from sales s1
يمكنك استخدام Max () الإجمالي. ربما تكون أقل كفاءة من البدائل الأخرى لأنك ستقوم بمجموعة مرتين
SELECT region,person,max(thousands) FROM
(SELECT region, person, count(*) as thousands
FROM sales
GROUP BY region, person) tmp
GROUP BY region, person
ORDER BY region, max(thousands) desc
للعثور على أفضل 5 مندوب مبيعات حسب المبيعات لكل منطقة
select *
from
(
select region,
[Customer Name],
rank() over(partition by region order by sum(sales) desc) as ranking
from Orders
group by region, [Customer Name]
) temp
where ranking between 1 and 5