Salut j'ai une installation de table. Qui détient un score pour chaque jour (plusieurs scores peuvent être signalés chaque jour et les deux seraient valables)
Je dois calculer le 90e centile, l'écart-type et la moyenne du score par mois.
Établissement:
Id Month Date score
1 Jan 1 5
1 Jan 1 5
1 Jan 2 3
1 Jan 3 4
1 Jan 4 4
1 Jan 5 4
1 Feb 1 5
1 Feb 1 5
1 Feb 2 3
1 Feb 3 4
1 Feb 4 4
1 Feb 5 4
Y a-t-il un moyen?
Merci de votre aide.
Vous pouvez utiliser la nouvelle suite de fonctions d'analyse introduite dans SQL Server 2012:
SELECT DISTINCT
[Month],
Mean = AVG(Score) OVER (PARTITION BY [Month]),
StdDev = STDEV(Score) OVER (PARTITION BY [Month]),
P90 = PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY Score) OVER (PARTITION BY [Month])
FROM my_table
Il existe 2 fonctions centiles: PERCENTILE_CONT
pour la distribution continue et PERCENTILE_DISC
pour la distribution discrète. Choisissez celui qui convient à vos besoins.
Voici la configuration ...
CREATE TABLE Facility (Id INT NOT NULL, Month nvarchar(3) NOT NULL, Date INT NOT NULL, score INT NOT NULL)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Jan', 1, 5)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Jan', 1, 5)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Jan', 2, 3)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Jan', 3, 4)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Jan', 4, 4)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Jan', 5, 4)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Feb', 1, 5)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Feb', 1, 5)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Feb', 2, 3)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Feb', 3, 4)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Feb', 4, 4)
INSERT INTO Facility (Id, Month, Date, score) VALUES (1, 'Feb', 5, 4)
Maintenant, l'écart-type et la moyenne sont assez simples: il y a des fonctions d'agrégation intégrées pour eux ...
SELECT
[Month],
AVG(CONVERT(real, score)) AS [Mean],
STDEV(score) AS [Standard Deviation]
FROM
Facility
GROUP BY
[Month]
Pour votre 90ème centile, vous devrez inventer une fonction ...
CREATE FUNCTION NintythPercentile(@Month nvarchar(3)) RETURNS INT AS
BEGIN
DECLARE @ReturnValue INT
SELECT
@ReturnValue = MIN(DerivedTopTenPercent.score) --AS [90th Percentile]
FROM
(
SELECT TOP 10 PERCENT
score
FROM
Facility
WHERE
[Month] = @Month
ORDER BY
score DESC
) DerivedTopTenPercent
RETURN @ReturnValue
END
Avec cette fonction en place, votre requête finale ressemblera à ceci ...
SELECT
[Month],
AVG(CONVERT(real, score)) AS [Mean],
STDEV(score) AS [Standard Deviation],
dbo.NintythPercentile([Month]) AS [90th Percentile]
FROM
Facility
GROUP BY
[Month]