SQL Server: Top 10 des vendeurs par semaine - et classement précédent
-
21-09-2019 - |
Question
select *
from
(
select year,
week,
salesperson,
count(*) as transactions,
rank() over(partition by week order by count(*) desc) as ranking
from sales
where year = '2010',
group by year,
week,
salesperson
) temp
where ranking <= 10
La requête renvoie une liste des 10 meilleurs vendeurs (en termes de nombre de transactions) pour chaque semaine de l'année.
Comment puis-je aller sur l'ajout de colonnes à mes résultats pour:
- la semaine précédente pour le classement de cette vendeur
- Total des semaines dans le Top 10 cette année
- semaines consécutives dans le Top 10 (à partir de la semaine 1)
- semaines consécutives dans le Top 10 (à partir de l'année précédente, si possible)
Pouvez-vous donner des conseils généraux sur la façon de s'y prendre ce genre de problèmes?
PS: Utilisation d'un serveur SQL 2008
La solution
Mon conseil est de faire les autres requêtes séparément dans les vues et les rejoindre par saleperson (que je suppose est la clé)
La logique est cette requête est agréable et propre et facile à suivre. Sinon - Je pense que la façon d'attaquer ce serait de commencer à écrire des fonctions TSQL pour calculer les autres valeurs, mais je pense que ces fonctions auront les requêtes en eux de toute façon
.Autres conseils
En fait, je ne suis pas convaincu que Vues sont la meilleure façon d'aller. Vous pouvez faire ce genre de logique de CTE et de combiner la chose entière en une seule requête. Par exemple, voici ce que j'ai pour tout sauf la logique consécutive:
;With
SalesDateParts As
(
Select DatePart(wk, SaleDate) As WeekNum, DatePart(yy, SaleDate) As [Year], SalesPersonId
From #Sales
)
, SalesByWeek As
(
Select [Year], WeekNum, SalesPersonId, Count(*) As SaleCount
, RANK() OVER( PARTITION BY [Year], [WeekNum] ORDER BY Count(*) DESC ) As SaleRank
From SalesDateParts
Group By [Year], WeekNum, SalesPersonId
)
, PrevWeekTopSales As
(
Select [Year], [WeekNum], SalesPersonId, SaleCount
From SalesByWeek
Where [Year] = DatePart(yyyy, DateAdd(d, -7, CURRENT_TIMESTAMP))
And WeekNum = DatePart(wk, DateAdd(d, -7, CURRENT_TIMESTAMP))
)
, WeeksInTop10 As
(
Select SalesPersonId, Count(*) As Top10Count
From SalesByWeek
Where SaleRank <= 10
Group By SalesPersonId
)
Select *
From Salespersons
Left Join WeeksInTop10
On WeeksInTop10.SalesPersonId = SalesPersons.SalesPersonId
Left Join PrevWeekTopSales
On PrevWeekTopSales.SalesPersonId = SalesPersons.SalesPersonId
La logique de « consécutive » va probablement exiger une table de calendrier qui contient une valeur pour chaque jour ainsi que des colonnes pour l'année et la semaine de la date indiquée.