SQL Server - Top SalePerson pro Region
-
21-09-2019 - |
Frage
SELECT region, person, sum(dollars) as thousands
FROM sales
GROUP BY region, person
ORDER BY region, sum(dollars) desc
Die obige SQL erstellt eine vollständige Liste von Vertriebsmitarbeitern pro Region wie dieser
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
Wenn ich nur daran interessiert bin, den Top -Verkäufer pro Region (wie unten) zu zeigen, wie kann ich das am besten tun?
region person thousands
canada mike smith $114
usa john doe $253
europe pieter tsu $546
Lösung
Ich habe so etwas wie Burnall vorgeschlagen. Ich bekam nicht viel Liebe mit dem Teil "Top 1 mit Krawatten", also machte ich das Ganze zu einer Unterabfrage und entschied mich für Reihen, bei denen Ranking = 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
Beachten Sie, dass dies auch für Krawatten funktioniert, da Rank () das gleiche Ranking für die gleiche Summen platziert.
Andere Tipps
Mit SQL Server 2005+ können Sie dies mit a tun ZEILENNUMMER()
Schauen Sie sich dieses vollständige Beispiel an.
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
In SQL Server 2005 und oben verwenden Sie ROW_NUMBER
mit PARTITION BY
. Das Folgende sollte funktionieren (nicht getestet und wahrscheinlich verkürzt werden):
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
Zunächst verstehe ich nicht, warum Count (*) in $ ist. Meine Lösung ähnelt vorhanden, aber kürzer und ich glaube schneller
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
Das ist nicht zu schwierig. Diese Abfrage wird genau das tun, was Sie wollen.
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
Sie können das max () Aggregat verwenden. Es ist wahrscheinlich weniger effizient als die anderen Alternativen, da Sie zweimal Gruppen machen
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
Top 5 Verkäufer nach Verkäufen für jede Region zu finden
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